From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51215) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDAgM-0005dx-2O for qemu-devel@nongnu.org; Wed, 15 Jun 2016 09:16:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bDAgG-0001Jz-NY for qemu-devel@nongnu.org; Wed, 15 Jun 2016 09:16:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37708) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDAgG-0001Jt-F3 for qemu-devel@nongnu.org; Wed, 15 Jun 2016 09:16:28 -0400 References: <1465994350-12256-1-git-send-email-pbonzini@redhat.com> From: Laszlo Ersek Message-ID: <506b0baf-3bd9-f0fc-2666-825f13b0fe84@redhat.com> Date: Wed, 15 Jun 2016 15:16:22 +0200 MIME-Version: 1.0 In-Reply-To: <1465994350-12256-1-git-send-email-pbonzini@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] scsi: esp: clean up handle_ti/esp_do_dma if s->do_cmd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , qemu-devel@nongnu.org Cc: ppandit@redhat.com, qiang6-s@360.cn On 06/15/16 14:39, Paolo Bonzini wrote: > Avoid duplicated code between esp_do_dma and handle_ti. esp_do_dma > has the same code that handle_ti contains after the call to esp_do_dma; > but the code in handle_ti is never reached (... never reached after esp_do_dma() is called -- it is reached in general... but splitting hairs about this is not important) > because it is in an "else if". > Remove the else and also the pointless return. Yes, this looks correct. > esp_do_dma also has a partially dead assignment of the to_device > variable. Sink it to the point where it's actually used. You could sink it a bit more, I think, to just before the first use. > Finally, assert that the other caller of esp_do_dma (esp_transfer_data) > only transfers data and not a command. This is true because get_cmd > cancels the old request synchronously before its caller handle_satn_stop > sets do_cmd to 1. I didn't try to verify why the claim is true, but if the claim is true, then the assert() is valid, and fits in with the changes in esp_do_dma() and handle_ti() -- the logic taken over by handle_ti() from esp_do_dma() is not reached when esp_do_dma() is called by esp_transfer_data(), but then again, on that call path, the original logic was never reached anyway. (If the claim is wrong, we'll quickly find out with the assert() :)) ... So, I think if you wish, you could lower the "to_device" assignment a bit more. Either way: Reviewed-by: Laszlo Ersek And I guess Prasad will submit a new version of the buffer overflow fix, on top of this patch, according to your previous message . Thanks Laszlo > > Signed-off-by: Paolo Bonzini > --- > hw/scsi/esp.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c > index 3f08598..2bc5076 100644 > --- a/hw/scsi/esp.c > +++ b/hw/scsi/esp.c > @@ -245,21 +245,17 @@ static void esp_do_dma(ESPState *s) > uint32_t len; > int to_device; > > - to_device = (s->ti_size < 0); > len = s->dma_left; > if (s->do_cmd) { > trace_esp_do_dma(s->cmdlen, len); > s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); > - s->ti_size = 0; > - s->cmdlen = 0; > - s->do_cmd = 0; > - do_cmd(s, s->cmdbuf); > return; > } > if (s->async_len == 0) { > /* Defer until data is available. */ > return; > } > + to_device = (s->ti_size < 0); > if (len > s->async_len) { > len = s->async_len; > } > @@ -318,6 +314,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len) > { > ESPState *s = req->hba_private; > > + assert(!s->do_cmd); > trace_esp_transfer_data(s->dma_left, s->ti_size); > s->async_len = len; > s->async_buf = scsi_req_get_buf(req); > @@ -358,13 +355,13 @@ static void handle_ti(ESPState *s) > s->dma_left = minlen; > s->rregs[ESP_RSTAT] &= ~STAT_TC; > esp_do_dma(s); > - } else if (s->do_cmd) { > + } > + if (s->do_cmd) { > trace_esp_handle_ti_cmd(s->cmdlen); > s->ti_size = 0; > s->cmdlen = 0; > s->do_cmd = 0; > do_cmd(s, s->cmdbuf); > - return; > } > } > >