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: 111899 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6E5kkDq027362 for ; Wed, 14 Jul 2010 05:46:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751897Ab0GNFqn (ORCPT ); Wed, 14 Jul 2010 01:46:43 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:48415 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751721Ab0GNFqg (ORCPT ); Wed, 14 Jul 2010 01:46:36 -0400 Received: by bwz1 with SMTP id 1so679020bwz.19 for ; Tue, 13 Jul 2010 22:46:35 -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 Cc: avi@redhat.com, paul@codesourcery.com, kvm@vger.kernel.org, qemu-devel@nongnu.org, Eduard - Gabriel Munteanu Subject: [RFC PATCH 4/7] ide: IOMMU support 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> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 14 Jul 2010 05:46:46 +0000 (UTC) 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;