net: smc91c111: gate can_receive() on rx FIFO having a slot
Return false from can_receive() when the FIFO doesn't have a free RX slot. This fixes a bug in the current code where the allocated buffer is freed before the fifo pop, triggering a premature flush of queued RX packets. It also will handle a corner case, where the guest manually frees the allocated buffer before popping the rx FIFO (hence it is not enough to just delay the flush_queued_packets()). Reported-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> Reviewed-by: Fam Zheng <famz@redhat.com> Tested-by: Richard Purdie <richard.purdie@linuxfoundation.org> Message-id: 97bfdfc5cbce0bd5e0cbbbff35ce7a1bf6f8603d.1441873621.git.crosthwaite.peter@gmail.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									8d06b14927
								
							
						
					
					
						commit
						e62cb54cd5
					
				| 
						 | 
					@ -129,7 +129,8 @@ static int smc91c111_can_receive(smc91c111_state *s)
 | 
				
			||||||
    if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
 | 
					    if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (s->allocated == (1 << NUM_PACKETS) - 1) {
 | 
					    if (s->allocated == (1 << NUM_PACKETS) - 1 ||
 | 
				
			||||||
 | 
					        s->rx_fifo_len == NUM_PACKETS) {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
| 
						 | 
					@ -182,6 +183,7 @@ static void smc91c111_pop_rx_fifo(smc91c111_state *s)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        s->int_level &= ~INT_RCV;
 | 
					        s->int_level &= ~INT_RCV;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    smc91c111_flush_queued_packets(s);
 | 
				
			||||||
    smc91c111_update(s);
 | 
					    smc91c111_update(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue