iommu/vt-d: Make first level IOVA canonical

First-level translation restricts the input-address to a canonical
address (i.e., address bits 63:N have the same value as address
bit [N-1], where N is 48-bits with 4-level paging and 57-bits with
5-level paging). (section 3.6 in the spec)

This makes first level IOVA canonical by using IOVA with bit [N-1]
always cleared.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
Lu Baolu 2020-01-02 08:18:19 +08:00 committed by Joerg Roedel
parent 33cd6e642d
commit cb8b892dce
1 changed files with 15 additions and 2 deletions

View File

@ -3505,8 +3505,21 @@ static unsigned long intel_alloc_iova(struct device *dev,
{
unsigned long iova_pfn;
/* Restrict dma_mask to the width that the iommu can handle */
dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
/*
* Restrict dma_mask to the width that the iommu can handle.
* First-level translation restricts the input-address to a
* canonical address (i.e., address bits 63:N have the same
* value as address bit [N-1], where N is 48-bits with 4-level
* paging and 57-bits with 5-level paging). Hence, skip bit
* [N-1].
*/
if (domain_use_first_level(domain))
dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw - 1),
dma_mask);
else
dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw),
dma_mask);
/* Ensure we reserve the whole size-aligned region */
nrpages = __roundup_pow_of_two(nrpages);