mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-10-31 00:13:27 +00:00 
			
		
		
		
	Added a new patch to the 4.11 and 4.9 kernels based on a patch submitted to stable: https://patchwork.kernel.org/patch/9829039/ This patch fixes a off-by-one error in the VMBus code. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 74c01ca434a7fa426397d3c4c084676b0ed46aaa Mon Sep 17 00:00:00 2001
 | |
| From: Vitaly Kuznetsov <vkuznets@redhat.com>
 | |
| Date: Mon, 14 Dec 2015 19:02:00 -0800
 | |
| Subject: [PATCH 22/44] Drivers: hv: remove code duplication between
 | |
|  vmbus_recvpacket()/vmbus_recvpacket_raw()
 | |
| 
 | |
| vmbus_recvpacket() and vmbus_recvpacket_raw() are almost identical but
 | |
| there are two discrepancies:
 | |
| 1) vmbus_recvpacket() doesn't propagate errors from hv_ringbuffer_read()
 | |
|    which looks like it is not desired.
 | |
| 2) There is an error message printed in packetlen > bufferlen case in
 | |
|    vmbus_recvpacket(). I'm removing it as it is usless for users to see
 | |
|    such messages and /vmbus_recvpacket_raw() doesn't have it.
 | |
| 
 | |
| Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
 | |
| Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
 | |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| (cherry picked from commit 667d374064b0cc48b6122101b287908d1b392bdb)
 | |
| ---
 | |
|  drivers/hv/channel.c | 65 ++++++++++++++++++----------------------------------
 | |
|  1 file changed, 22 insertions(+), 43 deletions(-)
 | |
| 
 | |
| diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
 | |
| index b00cdfb725de..def21d34f3ea 100644
 | |
| --- a/drivers/hv/channel.c
 | |
| +++ b/drivers/hv/channel.c
 | |
| @@ -924,8 +924,10 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
 | |
|   *
 | |
|   * Mainly used by Hyper-V drivers.
 | |
|   */
 | |
| -int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 | |
| -			u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
 | |
| +static inline int
 | |
| +__vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 | |
| +		   u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
 | |
| +		   bool raw)
 | |
|  {
 | |
|  	struct vmpacket_descriptor desc;
 | |
|  	u32 packetlen;
 | |
| @@ -943,27 +945,34 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 | |
|  		return 0;
 | |
|  
 | |
|  	packetlen = desc.len8 << 3;
 | |
| -	userlen = packetlen - (desc.offset8 << 3);
 | |
| +	if (!raw)
 | |
| +		userlen = packetlen - (desc.offset8 << 3);
 | |
| +	else
 | |
| +		userlen = packetlen;
 | |
|  
 | |
|  	*buffer_actual_len = userlen;
 | |
|  
 | |
| -	if (userlen > bufferlen) {
 | |
| -
 | |
| -		pr_err("Buffer too small - got %d needs %d\n",
 | |
| -			   bufferlen, userlen);
 | |
| -		return -ETOOSMALL;
 | |
| -	}
 | |
| +	if (userlen > bufferlen)
 | |
| +		return -ENOBUFS;
 | |
|  
 | |
|  	*requestid = desc.trans_id;
 | |
|  
 | |
|  	/* Copy over the packet to the user buffer */
 | |
|  	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
 | |
| -			     (desc.offset8 << 3), &signal);
 | |
| +				 raw ? 0 : desc.offset8 << 3, &signal);
 | |
|  
 | |
|  	if (signal)
 | |
|  		vmbus_setevent(channel);
 | |
|  
 | |
| -	return 0;
 | |
| +	return ret;
 | |
| +}
 | |
| +
 | |
| +int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 | |
| +		     u32 bufferlen, u32 *buffer_actual_len,
 | |
| +		     u64 *requestid)
 | |
| +{
 | |
| +	return __vmbus_recvpacket(channel, buffer, bufferlen,
 | |
| +				  buffer_actual_len, requestid, false);
 | |
|  }
 | |
|  EXPORT_SYMBOL(vmbus_recvpacket);
 | |
|  
 | |
| @@ -974,37 +983,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
 | |
|  			      u32 bufferlen, u32 *buffer_actual_len,
 | |
|  			      u64 *requestid)
 | |
|  {
 | |
| -	struct vmpacket_descriptor desc;
 | |
| -	u32 packetlen;
 | |
| -	int ret;
 | |
| -	bool signal = false;
 | |
| -
 | |
| -	*buffer_actual_len = 0;
 | |
| -	*requestid = 0;
 | |
| -
 | |
| -
 | |
| -	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
 | |
| -			     sizeof(struct vmpacket_descriptor));
 | |
| -	if (ret != 0)
 | |
| -		return 0;
 | |
| -
 | |
| -
 | |
| -	packetlen = desc.len8 << 3;
 | |
| -
 | |
| -	*buffer_actual_len = packetlen;
 | |
| -
 | |
| -	if (packetlen > bufferlen)
 | |
| -		return -ENOBUFS;
 | |
| -
 | |
| -	*requestid = desc.trans_id;
 | |
| -
 | |
| -	/* Copy over the entire packet to the user buffer */
 | |
| -	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0,
 | |
| -				 &signal);
 | |
| -
 | |
| -	if (signal)
 | |
| -		vmbus_setevent(channel);
 | |
| -
 | |
| -	return ret;
 | |
| +	return __vmbus_recvpacket(channel, buffer, bufferlen,
 | |
| +				  buffer_actual_len, requestid, true);
 | |
|  }
 | |
|  EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
 | |
| -- 
 | |
| 2.13.0
 | |
| 
 |