Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: fix bus_dmamap_destroy with bounce buffers
To:
Stefan Fritsch <sf@openbsd.org>
Cc:
tech@openbsd.org
Date:
Tue, 20 Aug 2024 14:09:51 +0200

Download raw body.

Thread
On Tue, Aug 20, 2024 at 09:55:59AM +0200, Stefan Fritsch wrote:
> Hi,
> 
> with bounce buffers, we must pass a larger size to free(). Otherwise 
> various drivers (azalia, xhci) cause a panic if bounce buffering is 
> enabled on KVM/qemu.
> 
> ok?

guest with bounce buffers tested on vmd hypervisor; OK bluhm@

> diff --git a/sys/arch/amd64/amd64/bus_dma.c b/sys/arch/amd64/amd64/bus_dma.c
> index 6ad6583bce9..e758ea9ea05 100644
> --- a/sys/arch/amd64/amd64/bus_dma.c
> +++ b/sys/arch/amd64/amd64/bus_dma.c
> @@ -223,12 +223,18 @@ _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
>  	size_t mapsize;
>  	struct vm_page **pg;
>  	struct pglist mlist;
> +	int use_bounce_buffer = cpu_sev_guestmode || FORCE_BOUNCE_BUFFER;
>  
>  	if (map->_dm_pgva) {
>  		km_free((void *)map->_dm_pgva, map->_dm_npages << PGSHIFT,
>  		    &kv_any, &kp_none);
>  	}
>  
> +	mapsize = sizeof(struct bus_dmamap) +
> +		(sizeof(bus_dma_segment_t) * (map->_dm_segcnt - 1));
> +	if (use_bounce_buffer)
> +		mapsize += sizeof(struct vm_page *) * map->_dm_npages;
> +
>  	if (map->_dm_pages) {
>  		TAILQ_INIT(&mlist);
>  		for (pg = map->_dm_pages; map->_dm_npages--; pg++) {
> @@ -237,8 +243,6 @@ _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
>  		uvm_pglistfree(&mlist);
>  	}
>  
> -	mapsize = sizeof(struct bus_dmamap) +
> -		(sizeof(bus_dma_segment_t) * (map->_dm_segcnt - 1));
>  	free(map, M_DEVBUF, mapsize);
>  }
>