mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 08:44:14 +08:00
iommufd for 6.5
Just two RC syzkaller fixes, both for the same basic issue, using the area pointer during an access forced unmap while the locks protecting it were let go. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCZJmGygAKCRCFwuHvBreF YVNSAQC7SgejTvwD6EYXr8AUDko1v0G0M/o60OrWIuC7xWiFPQD/RDwtItRLzf4h i+YCfMtn/7IB/uV/sRTF4m0HzudcDAM= =0fm4 -----END PGP SIGNATURE----- Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd Pull iommufd updates from Jason Gunthorpe: "Just two syzkaller fixes, both for the same basic issue: using the area pointer during an access forced unmap while the locks protecting it were let go" * tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd: iommufd: Call iopt_area_contig_done() under the lock iommufd: Do not access the area pointer after unlocking
This commit is contained in:
commit
31929ae008
@ -553,8 +553,8 @@ void iommufd_access_unpin_pages(struct iommufd_access *access,
|
||||
iopt_area_iova_to_index(
|
||||
area,
|
||||
min(last_iova, iopt_area_last_iova(area))));
|
||||
up_read(&iopt->iova_rwsem);
|
||||
WARN_ON(!iopt_area_contig_done(&iter));
|
||||
up_read(&iopt->iova_rwsem);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, IOMMUFD);
|
||||
|
||||
|
@ -458,6 +458,7 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
|
||||
{
|
||||
struct iopt_area *area;
|
||||
unsigned long unmapped_bytes = 0;
|
||||
unsigned int tries = 0;
|
||||
int rc = -ENOENT;
|
||||
|
||||
/*
|
||||
@ -484,19 +485,26 @@ again:
|
||||
goto out_unlock_iova;
|
||||
}
|
||||
|
||||
if (area_first != start)
|
||||
tries = 0;
|
||||
|
||||
/*
|
||||
* num_accesses writers must hold the iova_rwsem too, so we can
|
||||
* safely read it under the write side of the iovam_rwsem
|
||||
* without the pages->mutex.
|
||||
*/
|
||||
if (area->num_accesses) {
|
||||
size_t length = iopt_area_length(area);
|
||||
|
||||
start = area_first;
|
||||
area->prevent_access = true;
|
||||
up_write(&iopt->iova_rwsem);
|
||||
up_read(&iopt->domains_rwsem);
|
||||
iommufd_access_notify_unmap(iopt, area_first,
|
||||
iopt_area_length(area));
|
||||
if (WARN_ON(READ_ONCE(area->num_accesses)))
|
||||
|
||||
iommufd_access_notify_unmap(iopt, area_first, length);
|
||||
/* Something is not responding to unmap requests. */
|
||||
tries++;
|
||||
if (WARN_ON(tries > 100))
|
||||
return -EDEADLOCK;
|
||||
goto again;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user