From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org, Anthony Liguori <anthony@codemonkey.ws>
Cc: kwolf@redhat.com, Jes.Sorensen@redhat.com,
Alex Williamson <alex.williamson@redhat.com>,
agraf@suse.de, stefanha@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCHv2 3/3] e1000: verify we have buffers, upfront
Date: Tue, 15 Feb 2011 18:27:55 +0200 [thread overview]
Message-ID: <577246d76cde25110fa46428340b504da779aa73.1297787220.git.mst@redhat.com> (raw)
In-Reply-To: <cover.1297787220.git.mst@redhat.com>
The spec says: Any descriptor with a non-zero status byte has been
processed by the hardware, and is ready to be handled by the software.
Thus, once we change a descriptor status to non-zero we should
never move the head backwards and try to reuse this
descriptor from hardware.
This actually happened with a multibuffer packet
that arrives when we don't have enough buffers.
Fix by checking that we have enough buffers upfront
so we never need to discard the packet midway through.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/e1000.c | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/hw/e1000.c b/hw/e1000.c
index 2943a1a..0a4574c 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -631,6 +631,24 @@ e1000_can_receive(VLANClientState *nc)
return (s->mac_reg[RCTL] & E1000_RCTL_EN);
}
+static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
+{
+ int bufs;
+ /* Fast-path short packets */
+ if (total_size <= s->rxbuf_size) {
+ return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov;
+ }
+ if (s->mac_reg[RDH] < s->mac_reg[RDT]) {
+ bufs = s->mac_reg[RDT] - s->mac_reg[RDH];
+ } else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) {
+ bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) +
+ s->mac_reg[RDT] - s->mac_reg[RDH];
+ } else {
+ return false;
+ }
+ return total_size <= bufs * s->rxbuf_size;
+}
+
static ssize_t
e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
{
@@ -671,17 +689,15 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
rdh_start = s->mac_reg[RDH];
desc_offset = 0;
total_size = size + fcs_len(s);
+ if (!e1000_has_rxbufs(s, total_size)) {
+ set_ics(s, 0, E1000_ICS_RXO);
+ return -1;
+ }
do {
desc_size = total_size - desc_offset;
if (desc_size > s->rxbuf_size) {
desc_size = s->rxbuf_size;
}
- if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
- /* Discard all data written so far */
- s->mac_reg[RDH] = rdh_start;
- set_ics(s, 0, E1000_ICS_RXO);
- return -1;
- }
base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
sizeof(desc) * s->mac_reg[RDH];
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
--
1.7.3.2.91.g446ac
next prev parent reply other threads:[~2011-02-15 16:28 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-15 16:27 [Qemu-devel] [PATCHv2 0/3] e1000: multi-buffer packet support Michael S. Tsirkin
2011-02-15 16:27 ` [Qemu-devel] [PATCHv2 1/3] " Michael S. Tsirkin
2011-02-15 16:27 ` [Qemu-devel] [PATCHv2 2/3] e1000: clear EOP for multi-buffer descriptors Michael S. Tsirkin
2011-02-15 16:27 ` Michael S. Tsirkin [this message]
2011-02-16 11:37 ` [Qemu-devel] Re: [PATCHv2 0/3] e1000: multi-buffer packet support Stefan Hajnoczi
2011-02-17 0:05 ` [Qemu-devel] " Alex Williamson
2011-02-17 12:04 ` [Qemu-devel] " Kevin Wolf
2011-02-20 14:29 ` [Qemu-devel] " Aurelien Jarno
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=577246d76cde25110fa46428340b504da779aa73.1297787220.git.mst@redhat.com \
--to=mst@redhat.com \
--cc=Jes.Sorensen@redhat.com \
--cc=agraf@suse.de \
--cc=alex.williamson@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).