From patchwork Wed Jul 14 05:45:04 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduard - Gabriel Munteanu X-Patchwork-Id: 58839 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 653691007D2 for ; Wed, 14 Jul 2010 15:50:31 +1000 (EST) Received: from localhost ([127.0.0.1]:40841 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OYurU-00010C-EF for incoming@patchwork.ozlabs.org; Wed, 14 Jul 2010 01:50:28 -0400 Received: from [140.186.70.92] (port=39882 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OYunv-00089N-A6 for qemu-devel@nongnu.org; Wed, 14 Jul 2010 01:46:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OYunt-0008Ob-4l for qemu-devel@nongnu.org; Wed, 14 Jul 2010 01:46:47 -0400 Received: from mail-bw0-f45.google.com ([209.85.214.45]:61739) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OYuns-0008Ny-Q2 for qemu-devel@nongnu.org; Wed, 14 Jul 2010 01:46:45 -0400 Received: by bwz19 with SMTP id 19so541041bwz.4 for ; Tue, 13 Jul 2010 22:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references; bh=KM4vCYMAOaTJS4MzYgW/anPaV6b1RjKv3FcOzDESI6Q=; b=N3OMFPSp+plxQtOczLRha4KLArN/d+vUGJUIPK/vvlMyUrnOhRb9kKwU+uvWAJBNku s91S0Bk3vy0O1PCP7KJ2jQfoSQwALUt2YXNaulGIjJLTSl3zoMhZRrL26ydJC456OHsh 8+MYEezeBNFXIjXbYuEY1npx/AvlHSP5sZHQc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=VftfFXGnAZ8iNGzANUyTvDF6Ev8JT98fLcdOvs89m/SZEy+hgXtAiqVCyv1PtR9QM3 cvPmUi9UtkGeJbduYYW+8GYkp6IhkLv9eMT/QsZrRXJuX6rQA46AJLuvC0W41NXtN9JJ tzAa+rbwkSm9NngfOqgel9P4950jUkPx6yQnc= Received: by 10.204.160.66 with SMTP id m2mr13081257bkx.69.1279086395102; Tue, 13 Jul 2010 22:46:35 -0700 (PDT) Received: from localhost ([188.25.93.67]) by mx.google.com with ESMTPS id g11sm29670898bkw.22.2010.07.13.22.46.34 (version=SSLv3 cipher=RC4-MD5); Tue, 13 Jul 2010 22:46:34 -0700 (PDT) From: Eduard - Gabriel Munteanu To: joro@8bytes.org Date: Wed, 14 Jul 2010 08:45:04 +0300 Message-Id: <1279086307-9596-5-git-send-email-eduard.munteanu@linux360.ro> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1279086307-9596-1-git-send-email-eduard.munteanu@linux360.ro> References: <1279086307-9596-1-git-send-email-eduard.munteanu@linux360.ro> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: qemu-devel@nongnu.org, Eduard - Gabriel Munteanu , avi@redhat.com, kvm@vger.kernel.org, paul@codesourcery.com Subject: [Qemu-devel] [RFC PATCH 4/7] ide: IOMMU support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Memory accesses must go through the IOMMU layer. Signed-off-by: Eduard - Gabriel Munteanu --- hw/ide/core.c | 46 +++++++++++++++++++++++++++++++--------------- 1 files changed, 31 insertions(+), 15 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 0b3b7c2..7f8f7df 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "qemu-timer.h" #include "sysemu.h" #include "dma.h" @@ -433,7 +434,12 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) uint32_t addr; uint32_t size; } prd; - int l, len; + int l, len, err, io_len; + struct iommu *iommu; + DeviceState *dev; + target_phys_addr_t io_addr; + + iommu = iommu_get(s->bus->qbus.parent, &dev); qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1); s->io_buffer_size = 0; @@ -443,7 +449,7 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return s->io_buffer_size != 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + err = iommu_read(iommu, dev, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -455,11 +461,22 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) bm->cur_prd_last = (prd.size & 0x80000000); } l = bm->cur_prd_len; - if (l > 0) { - qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); - bm->cur_prd_addr += l; - bm->cur_prd_len -= l; - s->io_buffer_size += l; + while (l > 0) { + /* + * In case translation / access checking fails no + * transfer happens but we pretend it went through. + */ + err = iommu_translate(iommu, dev, bm->cur_prd_addr, + &io_addr, &io_len, !is_write); + if (!err) { + if (io_len > l) + io_len = l; + qemu_sglist_add(&s->sg, io_addr, io_len); + } + bm->cur_prd_addr += io_len; + bm->cur_prd_len -= io_len; + s->io_buffer_size += io_len; + l -= io_len; } } return 1; @@ -516,6 +533,10 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) uint32_t size; } prd; int l, len; + struct iommu *iommu; + DeviceState *dev; + + iommu = iommu_get(s->bus->qbus.parent, &dev); for(;;) { l = s->io_buffer_size - s->io_buffer_index; @@ -526,7 +547,7 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + iommu_read(iommu, dev, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -540,13 +561,8 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) if (l > bm->cur_prd_len) l = bm->cur_prd_len; if (l > 0) { - if (is_write) { - cpu_physical_memory_write(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); - } else { - cpu_physical_memory_read(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); - } + iommu_rw(iommu, dev, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l, is_write); bm->cur_prd_addr += l; bm->cur_prd_len -= l; s->io_buffer_index += l;