NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-arm/55737: Apparent bug in evbarm64 DMA code causes filesystem corruption



The following reply was made to PR port-arm/55737; it has been noted by GNATS.

From: Nick Hudson <nick.hudson%gmx.co.uk@localhost>
To: matthew green <mrg%eterna.com.au@localhost>, gnats-bugs%netbsd.org@localhost,
 rmtodd%servalan.servalan.com@localhost
Cc: port-arm-maintainer%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
 netbsd-bugs%netbsd.org@localhost
Subject: Re: port-arm/55737: Apparent bug in evbarm64 DMA code causes
 filesystem corruption
Date: Tue, 20 Oct 2020 09:03:57 +0100

 This is a multi-part message in MIME format.
 --------------64740B43E995EA09E8BB3D94
 Content-Type: text/plain; charset=utf-8; format=flowed
 Content-Transfer-Encoding: quoted-printable
 
 
 On 20/10/2020 06:34, matthew green wrote:
 >> - fix the subset check to ensure that all the ranges in the parent tag =
 are
 >>    within the {min,max}_addr range.  If so we can just continue to use =
 the
 >>    parent tag.
 > this part of the patch i think is problematic.
 >
 > previously, subset started as false, and was transitioned
 > to true, and never back.
 >
 > now, it's as false, but it transitions back and forth to
 > have the last entry's value.
 >
 > i think both are wrong.  it should start true, and if any
 > entry is outside the parent range, set to false.
 
 You're right the code is flawed.
 
 I think this patch is correct and covers the case that your patch
 doesn't where there are no ranges in the parent tag.
 
 I think the virtio patch is still valid, however.
 
 Thanks,
 
 Nick
 
 
 --------------64740B43E995EA09E8BB3D94
 Content-Type: text/x-patch; charset=UTF-8;
  name="bus_dma.c.diff"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment;
  filename="bus_dma.c.diff"
 
 Index: sys/arch/arm/arm32/bus_dma.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvsroot/src/sys/arch/arm/arm32/bus_dma.c,v
 retrieving revision 1.123
 diff -u -p -r1.123 bus_dma.c
 =2D-- sys/arch/arm/arm32/bus_dma.c	8 Sep 2020 10:30:17 -0000	1.123
 +++ sys/arch/arm/arm32/bus_dma.c	20 Oct 2020 08:00:34 -0000
 @@ -1816,18 +1816,18 @@ _bus_dmatag_subregion(bus_dma_tag_t tag,
 
  #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
  	struct arm32_dma_range *dr;
 -	bool subset =3D false;
 +	bool subset =3D true;
  	size_t nranges =3D 0;
  	size_t i;
  	for (i =3D 0, dr =3D tag->_ranges; i < tag->_nranges; i++, dr++) {
  		/*
 -		 * Are all the ranges in the parent tag a subset of the new
 -		 * range? If yes, we can continue to use the parent tag.
 +		 * If the new {min,max}_addr are narrower than any of the
 +		 * ranges in the parent tag then we need a new tag;
 +		 * otherwise the parent tag is a subset of the new
 +		 * range and can continue to be used.
  		 */
 -		if (dr->dr_sysbase >=3D min_addr
 -		    && dr->dr_sysbase + dr->dr_len - 1 <=3D max_addr) {
 -			subset =3D true;
 -		} else {
 +		if (min_addr > dr->dr_sysbase
 +		    || max_addr < dr->dr_sysbase + dr->dr_len - 1) {
  			subset =3D false;
  		}
  		if (min_addr <=3D dr->dr_sysbase + dr->dr_len
 @@ -1835,6 +1835,10 @@ _bus_dmatag_subregion(bus_dma_tag_t tag,
  			nranges++;
  		}
  	}
 +	if (nranges =3D=3D 0) {
 +		nranges =3D 1;
 +		subset =3D false;
 +	}
  	if (subset) {
  		*newtag =3D tag;
  		/* if the tag must be freed, add a reference */
 @@ -1842,9 +1846,6 @@ _bus_dmatag_subregion(bus_dma_tag_t tag,
  			(tag->_tag_needs_free)++;
  		return 0;
  	}
 -	if (nranges =3D=3D 0) {
 -		nranges =3D 1;
 -	}
 
  	const size_t tagsize =3D sizeof(*tag) + nranges * sizeof(*dr);
  	if ((*newtag =3D kmem_intr_zalloc(tagsize,
 
 --------------64740B43E995EA09E8BB3D94--
 


Home | Main Index | Thread Index | Old Index