diff options
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
| -rw-r--r-- | drivers/iommu/amd_iommu.c | 16 | 
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b319e51c379b..f7cdd2ab7f11 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2608,7 +2608,12 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,  	/* Everything is mapped - write the right values into s->dma_address */  	for_each_sg(sglist, s, nelems, i) { -		s->dma_address += address + s->offset; +		/* +		 * Add in the remaining piece of the scatter-gather offset that +		 * was masked out when we were determining the physical address +		 * via (sg_phys(s) & PAGE_MASK) earlier. +		 */ +		s->dma_address += address + (s->offset & ~PAGE_MASK);  		s->dma_length   = s->length;  	} @@ -3164,21 +3169,24 @@ static void amd_iommu_get_resv_regions(struct device *dev,  		return;  	list_for_each_entry(entry, &amd_iommu_unity_map, list) { +		int type, prot = 0;  		size_t length; -		int prot = 0;  		if (devid < entry->devid_start || devid > entry->devid_end)  			continue; +		type   = IOMMU_RESV_DIRECT;  		length = entry->address_end - entry->address_start;  		if (entry->prot & IOMMU_PROT_IR)  			prot |= IOMMU_READ;  		if (entry->prot & IOMMU_PROT_IW)  			prot |= IOMMU_WRITE; +		if (entry->prot & IOMMU_UNITY_MAP_FLAG_EXCL_RANGE) +			/* Exclusion range */ +			type = IOMMU_RESV_RESERVED;  		region = iommu_alloc_resv_region(entry->address_start, -						 length, prot, -						 IOMMU_RESV_DIRECT); +						 length, prot, type);  		if (!region) {  			dev_err(dev, "Out of memory allocating dm-regions\n");  			return;  | 
