git: 9af32ef5643b - main - vtblk: Bypass iommu on powerpc

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Wed, 11 Jan 2023 03:43:41 UTC
The branch main has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=9af32ef5643bf35e1a2687269f2339dfb007ef36

commit 9af32ef5643bf35e1a2687269f2339dfb007ef36
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2022-12-28 06:23:05 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2023-01-11 03:42:04 +0000

    vtblk: Bypass iommu on powerpc
    
    Virtio operates with physical addresses, while busdma is designed to
    map these to produce bus addresses.  On most supported platforms,
    these two are interchangeable; on powerpc platforms, they are not.
    
    When on powerpc, set an IOMMU of NULL, which causes the powerpc busdma
    code to bypass the iommu mapping; this leaves us with the physical
    buffer addresses which the virtio host expects to see.
    
    Tested by:      alfredo
    Fixes:  782105f7c898 ("vtblk: Use busdma")
    Sponsored by:   https://www.patreon.com/cperciva
    Differential Revision:  https://reviews.freebsd.org/D37891
---
 sys/dev/virtio/block/virtio_blk.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c
index 41229bb6da2c..052017251c22 100644
--- a/sys/dev/virtio/block/virtio_blk.c
+++ b/sys/dev/virtio/block/virtio_blk.c
@@ -397,6 +397,15 @@ vtblk_attach(device_t dev)
 		goto fail;
 	}
 
+#ifdef __powerpc__
+	/*
+	 * Virtio uses physical addresses rather than bus addresses, so we
+	 * need to ask busdma to skip the iommu physical->bus mapping.  At
+	 * present, this is only a thing on the powerpc architectures.
+	 */
+	bus_dma_tag_set_iommu(sc->vtblk_dmat, NULL, NULL);
+#endif
+
 	error = vtblk_alloc_virtqueue(sc);
 	if (error) {
 		device_printf(dev, "cannot allocate virtqueue\n");
@@ -1070,9 +1079,8 @@ vtblk_request_execute_cb(void * callback_arg, bus_dma_segment_t * segs,
 
 	if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
 		/*
-		 * We cast bus_addr_t to vm_paddr_t here; this isn't valid on
-		 * all platforms, but we believe it works on all platforms
-		 * which are supported by virtio.
+		 * We cast bus_addr_t to vm_paddr_t here; since we skip the
+		 * iommu mapping (see vtblk_attach) this should be safe.
 		 */
 		for (i = 0; i < nseg; i++) {
 			error = sglist_append_phys(sg,