From: David Stevens <stevensd@chromium.org>
To: Robin Murphy <robin.murphy@arm.com>
Cc: Christoph Hellwig <hch@lst.de>, Joerg Roedel <joro@8bytes.org>,
Will Deacon <will@kernel.org>,
Sergey Senozhatsky <senozhatsky@chromium.org>,
Lu Baolu <baolu.lu@linux.intel.com>,
iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org,
David Stevens <stevensd@chromium.org>
Subject: [PATCH v2 5/9] dma-iommu: clear only necessary bytes
Date: Fri, 6 Aug 2021 19:34:19 +0900 [thread overview]
Message-ID: <20210806103423.3341285-6-stevensd@google.com> (raw)
In-Reply-To: <20210806103423.3341285-1-stevensd@google.com>
From: David Stevens <stevensd@chromium.org>
Only clear the padding bytes in bounce buffers, since syncing from the
original buffer already overwrites the non-padding bytes.
Signed-off-by: David Stevens <stevensd@chromium.org>
---
drivers/iommu/io-bounce-buffers.c | 64 +++++++++++++++++++++++++++++--
drivers/iommu/io-buffer-manager.c | 7 +---
2 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/io-bounce-buffers.c b/drivers/iommu/io-bounce-buffers.c
index c7c52a3f8bf7..ed05f593a195 100644
--- a/drivers/iommu/io-bounce-buffers.c
+++ b/drivers/iommu/io-bounce-buffers.c
@@ -296,14 +296,70 @@ bool io_bounce_buffers_unmap_sg(struct io_bounce_buffers *buffers,
io_bounce_buffers_unmap_sg_sync, &args);
}
+static void io_bounce_buffers_clear_padding(struct io_bounce_buffer_info *info,
+ size_t pad_hd_end,
+ size_t pad_tl_start)
+{
+ size_t idx, pad_hd_idx, pad_tl_idx, count;
+
+ count = info->size / PAGE_SIZE;
+ pad_hd_idx = pad_hd_end / PAGE_SIZE;
+ pad_tl_idx = pad_tl_start / PAGE_SIZE;
+
+ if (!IS_ALIGNED(pad_hd_end, PAGE_SIZE)) {
+ struct page *page = info->bounce_buffer[pad_hd_idx];
+ size_t len = offset_in_page(pad_hd_end);
+
+ memset_page(page, 0, 0, len);
+ arch_sync_dma_for_device(page_to_phys(page), 0, len);
+ }
+
+ if (!IS_ALIGNED(pad_tl_start, PAGE_SIZE)) {
+ size_t off = offset_in_page(pad_tl_start);
+ size_t len = PAGE_SIZE - off;
+ struct page *page = info->bounce_buffer[pad_tl_idx];
+
+ memset_page(page, off, 0, len);
+ arch_sync_dma_for_device(page_to_phys(page) + off, 0, len);
+
+ pad_tl_idx++;
+ }
+
+ idx = pad_hd_idx ? 0 : pad_tl_idx;
+ while (idx < count) {
+ struct page *page = info->bounce_buffer[idx++];
+
+ clear_highpage(page);
+ arch_sync_dma_for_device(page_to_phys(page), 0, PAGE_SIZE);
+ if (idx == pad_hd_idx)
+ idx = pad_tl_idx;
+ }
+}
+
static bool io_bounce_buffers_map_buffer(struct io_bounce_buffers *buffers,
struct io_bounce_buffer_info *info,
- int prot)
+ int prot, bool skiped_sync,
+ size_t offset, size_t orig_size)
{
unsigned int count = info->size >> PAGE_SHIFT;
struct sg_table sgt;
size_t mapped;
+ if (offset || offset + orig_size < info->size || skiped_sync) {
+ // Ensure that nothing is leaked to untrusted devices when
+ // mapping the buffer by clearing any part of the bounce buffer
+ // that wasn't already cleared by syncing.
+ size_t pad_hd_end, pad_tl_start;
+
+ if (skiped_sync) {
+ pad_hd_end = pad_tl_start = 0;
+ } else {
+ pad_hd_end = offset;
+ pad_tl_start = offset + orig_size;
+ }
+ io_bounce_buffers_clear_padding(info, pad_hd_end, pad_tl_start);
+ }
+
if (sg_alloc_table_from_pages(&sgt, info->bounce_buffer, count, 0,
info->size, GFP_ATOMIC))
return false;
@@ -338,7 +394,8 @@ bool io_bounce_buffers_map_page(struct io_bounce_buffers *buffers,
io_bounce_buffers_do_sync(buffers, info.bounce_buffer, offset,
page, offset, size, dir, prot, false);
- if (!io_bounce_buffers_map_buffer(buffers, &info, prot)) {
+ if (!io_bounce_buffers_map_buffer(buffers, &info, prot, skip_cpu_sync,
+ offset, size)) {
io_buffer_manager_release_buffer(&buffers->manager,
buffers->domain, info.iova,
false, NULL, NULL);
@@ -381,7 +438,8 @@ bool io_bounce_buffers_map_sg(struct io_bounce_buffers *buffers,
info.bounce_buffer, dir, prot,
false);
- if (!io_bounce_buffers_map_buffer(buffers, &info, prot)) {
+ if (!io_bounce_buffers_map_buffer(buffers, &info, prot, skip_cpu_sync,
+ 0, size)) {
io_buffer_manager_release_buffer(&buffers->manager,
buffers->domain, info.iova,
false, NULL, NULL);
diff --git a/drivers/iommu/io-buffer-manager.c b/drivers/iommu/io-buffer-manager.c
index 79b9759da928..587584fdf26b 100644
--- a/drivers/iommu/io-buffer-manager.c
+++ b/drivers/iommu/io-buffer-manager.c
@@ -37,13 +37,10 @@ static struct page **io_buffer_manager_alloc_pages(int count, unsigned int nid)
// pages first to make accessing the buffer cheaper.
for (i = 0; i < count; i++) {
pages[i] = alloc_pages_node(
- nid,
- GFP_ATOMIC | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN,
- 0);
+ nid, GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN, 0);
if (!pages[i]) {
pages[i] = alloc_pages_node(
- nid, GFP_ATOMIC | __GFP_ZERO | __GFP_HIGHMEM,
- 0);
+ nid, GFP_ATOMIC | __GFP_HIGHMEM, 0);
if (!pages[i]) {
io_buffer_manager_free_pages(pages, i);
return NULL;
--
2.32.0.605.g8dce9f2422-goog
next prev parent reply other threads:[~2021-08-06 10:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-06 10:34 [PATCH v2 0/9] Add dynamic iommu backed bounce buffers David Stevens
2021-08-06 10:34 ` [PATCH v2 1/9] Revert "iommu: Allow the dma-iommu api to use bounce buffers" David Stevens
2021-08-06 10:34 ` [PATCH v2 2/9] dma-iommu: expose a few helper functions to module David Stevens
2021-08-06 17:28 ` kernel test robot
2021-08-06 10:34 ` [PATCH v2 3/9] dma-iommu: bounce buffers for untrusted devices David Stevens
2021-08-06 15:53 ` kernel test robot
2021-08-10 1:19 ` Mi, Dapeng1
2021-08-10 1:41 ` David Stevens
2021-08-06 10:34 ` [PATCH v2 4/9] dma-iommu: remove extra buffer search on unmap David Stevens
2021-08-06 10:34 ` David Stevens [this message]
2021-08-06 10:34 ` [PATCH v2 6/9] dma-iommu: add bounce buffer pools David Stevens
2021-08-06 10:34 ` [PATCH v2 7/9] dma-iommu: support iommu bounce buffer optimization David Stevens
2021-08-06 10:34 ` [PATCH v2 8/9] dma-mapping: add persistent streaming mapping flag David Stevens
2021-08-06 10:34 ` [PATCH v2 9/9] drm/i915: use DMA_ATTR_PERSISTENT_STREAMING flag David Stevens
2022-05-24 12:27 ` [PATCH v2 0/9] Add dynamic iommu backed bounce buffers Niklas Schnelle
2022-05-27 1:25 ` David Stevens
2022-06-03 14:53 ` Niklas Schnelle
2022-06-06 1:24 ` David Stevens
2022-07-01 9:23 ` Niklas Schnelle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210806103423.3341285-6-stevensd@google.com \
--to=stevensd@chromium.org \
--cc=baolu.lu@linux.intel.com \
--cc=hch@lst.de \
--cc=iommu@lists.linux-foundation.org \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=senozhatsky@chromium.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox