mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: Fix off-by-one in iomem_deny_access() calls
iomem_deny_access() wraps rangeset_remove_range() which takes inclusive endpoints. All call sites in the GIC and ACPI code pass 'mfn + nr' (or 'mfn + 1' for single-page regions) as the end parameter, which causes one extra page beyond each region to be denied. For single-page regions, use 'mfn' as the end (denying exactly one page). For all multi-page regions, use 'mfn + nr - 1'. This matches the correct pattern used elsewhere, e.g. in device.c. Fixes:8300b3377e("arm/gic: Add a new callback to deny Dom0 access to GIC regions") Fixes:66158be465("ARM: ITS: Deny hardware domain access to ITS") Fixes:97e9875646("arm/acpi: Permit MMIO access of Xen unused devices for Dom0") Signed-off-by: Michal Orzel <michal.orzel@amd.com> Reviewed-by: Luca Fancellu <luca.fancellu@arm.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com> (cherry picked from commitf25fe2452b)
This commit is contained in:
1 parent
6610b4f3ac
commit
c635373c25
4 files changed
+10
-10
No files matched your search
@@ -47,7 +47,7 @@ static int __init acpi_iomem_deny_access(struct domain *d)
|
||||
{
|
||||
mfn = spcr->serial_port.address >> PAGE_SHIFT;
|
||||
/* Deny MMIO access for UART */
|
||||
rc = iomem_deny_access(d, mfn, mfn + 1);
|
||||
rc = iomem_deny_access(d, mfn, mfn);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1079,23 +1079,23 @@ static int gicv2_iomem_deny_access(struct domain *d)
|
||||
unsigned long mfn, nr;
|
||||
|
||||
mfn = dbase >> PAGE_SHIFT;
|
||||
rc = iomem_deny_access(d, mfn, mfn + 1);
|
||||
rc = iomem_deny_access(d, mfn, mfn);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
mfn = hbase >> PAGE_SHIFT;
|
||||
rc = iomem_deny_access(d, mfn, mfn + 1);
|
||||
rc = iomem_deny_access(d, mfn, mfn);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
mfn = cbase >> PAGE_SHIFT;
|
||||
nr = DIV_ROUND_UP(csize, PAGE_SIZE);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
mfn = vbase >> PAGE_SHIFT;
|
||||
return iomem_deny_access(d, mfn, mfn + nr);
|
||||
return iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
@@ -894,7 +894,7 @@ int gicv3_its_deny_access(struct domain *d)
|
||||
{
|
||||
mfn = paddr_to_pfn(its_data->addr);
|
||||
nr = PFN_UP(its_data->size);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
if ( rc )
|
||||
{
|
||||
printk("iomem_deny_access failed for %lx:%lx \r\n", mfn, nr);
|
||||
|
||||
@@ -1463,7 +1463,7 @@ static int gicv3_iomem_deny_access(struct domain *d)
|
||||
|
||||
mfn = dbase >> PAGE_SHIFT;
|
||||
nr = PFN_UP(SZ_64K);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
@@ -1475,7 +1475,7 @@ static int gicv3_iomem_deny_access(struct domain *d)
|
||||
{
|
||||
mfn = gicv3.rdist_regions[i].base >> PAGE_SHIFT;
|
||||
nr = PFN_UP(gicv3.rdist_regions[i].size);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
@@ -1484,7 +1484,7 @@ static int gicv3_iomem_deny_access(struct domain *d)
|
||||
{
|
||||
mfn = cbase >> PAGE_SHIFT;
|
||||
nr = PFN_UP(csize);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr);
|
||||
rc = iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
@@ -1493,7 +1493,7 @@ static int gicv3_iomem_deny_access(struct domain *d)
|
||||
{
|
||||
mfn = vbase >> PAGE_SHIFT;
|
||||
nr = PFN_UP(csize);
|
||||
return iomem_deny_access(d, mfn, mfn + nr);
|
||||
return iomem_deny_access(d, mfn, mfn + nr - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||