From patchwork Thu May 17 05:25:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 159811 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 31ED0B6FC4 for ; Thu, 17 May 2012 15:24:38 +1000 (EST) Received: from localhost ([::1]:55979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SUtCV-0005xa-SP for incoming@patchwork.ozlabs.org; Thu, 17 May 2012 01:24:35 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45486) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SUtCO-0005ww-B1 for qemu-devel@nongnu.org; Thu, 17 May 2012 01:24:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SUtCM-0006df-7u for qemu-devel@nongnu.org; Thu, 17 May 2012 01:24:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51348) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SUtCL-0006d6-Vi for qemu-devel@nongnu.org; Thu, 17 May 2012 01:24:26 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q4H5ONHp019951 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 17 May 2012 01:24:23 -0400 Received: from dhcp-8-146.nay.redhat.com (dhcp-8-146.nay.redhat.com [10.66.8.146]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q4H5OKuZ004309; Thu, 17 May 2012 01:24:21 -0400 To: aliguori@us.ibm.com, qemu-devel@nongnu.org, mst@redhat.com From: Jason Wang Date: Thu, 17 May 2012 13:25:43 +0800 Message-ID: <20120517052542.17932.58011.stgit@dhcp-8-146.nay.redhat.com> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: avi@redhat.com Subject: [Qemu-devel] [PATCH] rtl8139: validate rx ring before receiving packets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Commit ff71f2e8cacefae99179993204172bc65e4303df prevent the possible crash during initialization of linux driver by checking the operating mode.This seems too strict as: - the real card could still work in mode other than normal - some buggy driver who does not set correct opmode after eeprom access So, considering rx ring address were reset to zero (which could be safely trated as an address not intened to DMA to), in order to both letting old guest work and preventing the unexpected DMA to guest, we can forbid packet receiving when rx ring address is zero. Signed-off-by: Jason Wang Tested-by: Avi Kivity --- hw/rtl8139.c | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index eb22d04..3879121 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -781,6 +781,13 @@ static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high) #endif } +/* Workaround for buggy guest driver such as linux who allocates rx + * rings after the receiver were enabled. */ +static bool rtl8139_cp_rx_valid(RTL8139State *s) +{ + return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0); +} + static int rtl8139_can_receive(VLANClientState *nc) { RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -791,11 +798,8 @@ static int rtl8139_can_receive(VLANClientState *nc) return 1; if (!rtl8139_receiver_enabled(s)) return 1; - /* network/host communication happens only in normal mode */ - if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal) - return 0; - if (rtl8139_cp_receiver_enabled(s)) { + if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) { /* ??? Flow control not implemented in c+ mode. This is a hack to work around slirp deficiencies anyway. */ return 1; @@ -836,12 +840,6 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ return -1; } - /* check whether we are in normal mode */ - if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal) { - DPRINTF("not in normal op mode\n"); - return -1; - } - /* XXX: check this */ if (s->RxConfig & AcceptAllPhys) { /* promiscuous: receive all */ @@ -946,6 +944,10 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ if (rtl8139_cp_receiver_enabled(s)) { + if (!rtl8139_cp_rx_valid(s)) { + return size; + } + DPRINTF("in C+ Rx mode ================\n"); /* begin C+ receiver mode */