File xsa378-0b.patch of Package xen.26345
# Commit b75b3c62fe4afe381c6f74a07f614c0b39fe2f5d
# Date 2020-03-16 11:24:29 +0100
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
AMD/IOMMU: fix off-by-one in get_paging_mode() callers
amd_iommu_get_paging_mode() expects a count, not a "maximum possible"
value. Prior to b4f042236ae0 dropping the reference, the use of our mis-
named "max_page" in amd_iommu_domain_init() may have lead to such a
misunderstanding. In an attempt to avoid such confusion in the future,
rename the function's parameter and - while at it - convert it to an
inline function.
Also replace a literal 4 by an expression tying it to a wider use
constant, just like amd_iommu_quarantine_init() does.
Fixes: b4f042236ae0 ("AMD/IOMMU: Cease using a dynamic height for the IOMMU pagetables")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -222,15 +222,15 @@ static int __must_check allocate_domain_
return rc;
}
-static int get_paging_mode(unsigned long entries)
+static int get_paging_mode(unsigned long max_frames)
{
int level = 1;
- BUG_ON( !entries );
+ BUG_ON(!max_frames);
- while ( entries > PTE_PER_TABLE_SIZE )
+ while ( max_frames > PTE_PER_TABLE_SIZE )
{
- entries = PTE_PER_TABLE_ALIGN(entries) >> PTE_PER_TABLE_SHIFT;
+ max_frames = PTE_PER_TABLE_ALIGN(max_frames) >> PTE_PER_TABLE_SHIFT;
if ( ++level > 6 )
return -ENOMEM;
}
@@ -250,8 +250,10 @@ static int amd_iommu_domain_init(struct
* physical address space we give it, but this isn't known yet so use 4
* unilaterally.
*/
- hd->arch.paging_mode = is_hvm_domain(d)
- ? IOMMU_PAGING_MODE_LEVEL_4 : get_paging_mode(get_upper_mfn_bound());
+ hd->arch.paging_mode = get_paging_mode(
+ is_hvm_domain(d)
+ ? 1ul << (DEFAULT_DOMAIN_ADDRESS_WIDTH - PAGE_SHIFT)
+ : get_upper_mfn_bound() + 1);
return 0;
}