Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.5854
0007-e1000-verify-we-have-buffers-upfront.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0007-e1000-verify-we-have-buffers-upfront.patch of Package xen.5854
From: "Michael S. Tsirkin" <mst@redhat.com> Date: Tue, 15 Feb 2011 18:27:55 +0200 Subject: e1000: verify we have buffers, upfront Patch-mainline: v0.15.0-rc0 Git-commit: 322fd48afbed1ef7b834ac343a0c8687bcb33695 References: bnc#840196 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> Acked-by: Alex Williamson <alex.williamson@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Acked-by: Michal Kubecek <mkubecek@suse.cz> --- tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 28 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c index 7e791dc..18d7597 100644 --- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c +++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c @@ -622,6 +622,24 @@ e1000_can_receive(void *opaque) return (s->mac_reg[RCTL] & E1000_RCTL_EN && s->mac_reg[RDLEN] != 0); } +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 void e1000_receive(void *opaque, const uint8_t *buf, int size) { @@ -667,17 +685,15 @@ e1000_receive(void *opaque, const uint8_t *buf, int 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; + } 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; - } 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.8.1.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor