From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:47384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfVC3-0000TK-Ia for qemu-devel@nongnu.org; Thu, 23 May 2013 09:04:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UfVBu-0003L0-D1 for qemu-devel@nongnu.org; Thu, 23 May 2013 09:04:31 -0400 Received: from ozlabs.org ([203.10.76.45]:40964) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfVBt-0003KF-N0 for qemu-devel@nongnu.org; Thu, 23 May 2013 09:04:22 -0400 Date: Thu, 23 May 2013 22:05:33 +1000 From: David Gibson Message-ID: <20130523120533.GA26259@boomeroo.fritz.box> References: <1369133851-1894-1-git-send-email-pbonzini@redhat.com> <1369133851-1894-16-git-send-email-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="HcAYCG3uE/tztfnV" Content-Disposition: inline In-Reply-To: <1369133851-1894-16-git-send-email-pbonzini@redhat.com> Subject: Re: [Qemu-devel] [PATCH 15/30] memory: add address_space_valid List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: peter.maydell@linaro.org, qemu-devel@nongnu.org, jan.kiszka@gmail.com --HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 21, 2013 at 12:57:16PM +0200, Paolo Bonzini wrote: > The old-style IOMMU lets you check whether an access is valid in a > given DMAContext. There is no equivalent for AddressSpace in the > memory API, implement it with a lookup of the dispatch tree. I don't love the name - "address_space_valid" suggests to me it tests the validity of the whole address space, not a specific range. But an obviously better name doesn't quickly occur to me. Obviously I like the functionality, since I wrote that into the DMAContext stuff specifically to support the spapr_llan driver :). >=20 > Signed-off-by: Paolo Bonzini > --- > dma-helpers.c | 5 +++++ > exec.c | 25 +++++++++++++++++++++++++ > include/exec/memory.h | 14 ++++++++++++++ > include/sysemu/dma.h | 3 ++- > 4 files changed, 46 insertions(+), 1 deletion(-) >=20 > diff --git a/dma-helpers.c b/dma-helpers.c > index 272632f..2962b69 100644 > --- a/dma-helpers.c > +++ b/dma-helpers.c > @@ -298,6 +298,11 @@ bool iommu_dma_memory_valid(DMAContext *dma, dma_add= r_t addr, dma_addr_t len, > plen =3D len; > } > =20 > + if (!address_space_valid(dma->as, paddr, len, > + dir =3D=3D DMA_DIRECTION_FROM_DEVICE)) { > + return false; > + } > + > len -=3D plen; > addr +=3D plen; > } > diff --git a/exec.c b/exec.c > index 8d91221..8f1b507 100644 > --- a/exec.c > +++ b/exec.c > @@ -2079,6 +2079,31 @@ static void cpu_notify_map_clients(void) > } > } > =20 > +bool address_space_valid(AddressSpace *as, hwaddr addr, int len, bool is= _write) > +{ > + AddressSpaceDispatch *d =3D as->dispatch; > + MemoryRegionSection *section; > + int l; > + hwaddr page; > + > + while (len > 0) { > + page =3D addr & TARGET_PAGE_MASK; > + l =3D (page + TARGET_PAGE_SIZE) - addr; > + if (l > len) { > + l =3D len; > + } > + section =3D phys_page_find(d, addr >> TARGET_PAGE_BITS); > + if (section->mr =3D=3D &io_mem_unassigned || > + (is_write && section->mr->readonly)) { > + return false; > + } > + > + len -=3D l; > + addr +=3D l; > + } > + return true; > +} > + > /* Map a physical memory region into a host virtual address. > * May map a subset of the requested range, given by and returned in *pl= en. > * May return NULL if resources needed to perform the mapping are exhaus= ted. > diff --git a/include/exec/memory.h b/include/exec/memory.h > index 6ed593c..2e5fd11 100644 > --- a/include/exec/memory.h > +++ b/include/exec/memory.h > @@ -860,6 +860,20 @@ void address_space_write(AddressSpace *as, hwaddr ad= dr, > */ > void address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int= len); > =20 > +/* address_space_valid: check for validity of an address space range > + * > + * Check whether memory is assigned to the given address space range. > + * > + * For now, addr and len should be aligned to a page size. This limitat= ion > + * will be lifted in the future. > + * > + * @as: #AddressSpace to be accessed > + * @addr: address within that address space > + * @len: length of the area to be checked > + * @is_write: indicates the transfer direction > + */ > +bool address_space_valid(AddressSpace *as, hwaddr addr, int len, bool is= _write); > + > /* address_space_map: map a physical memory region into a host virtual a= ddress > * > * May map a subset of the requested range, given by and returned in @pl= en. > diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h > index a52c93a..2e239dc 100644 > --- a/include/sysemu/dma.h > +++ b/include/sysemu/dma.h > @@ -113,7 +113,8 @@ static inline bool dma_memory_valid(DMAContext *dma, > DMADirection dir) > { > if (!dma_has_iommu(dma)) { > - return true; > + return address_space_valid(dma->as, addr, len, > + dir =3D=3D DMA_DIRECTION_FROM_DEVICE); > } else { > return iommu_dma_memory_valid(dma, addr, len, dir); > } --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --HcAYCG3uE/tztfnV Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlGeBg0ACgkQaILKxv3ab8aHGgCdFVIzB1NtrKFWWhxsKP1M7pEv KC4AoIPuzz//CJODqhFXae8RznhJh7gW =/f/v -----END PGP SIGNATURE----- --HcAYCG3uE/tztfnV--