git: 6e2fc728d8da - stable/13 - AMD-vi: Fortify IVHD device_identify process
Ka Ho Ng
khng at FreeBSD.org
Fri Aug 27 13:08:19 UTC 2021
The branch stable/13 has been updated by khng:
URL: https://cgit.FreeBSD.org/src/commit/?id=6e2fc728d8da06d4f849061cce6540fdc2ea6000
commit 6e2fc728d8da06d4f849061cce6540fdc2ea6000
Author: Ka Ho Ng <khng at FreeBSD.org>
AuthorDate: 2021-04-19 08:07:03 +0000
Commit: Ka Ho Ng <khng at FreeBSD.org>
CommitDate: 2021-08-27 13:05:58 +0000
AMD-vi: Fortify IVHD device_identify process
- Use malloc(9) to allocate ivhd_hdrs list. The previous assumption
that there are at most 10 IVHDs in a system is not true. A counter
example would be a system with 4 IOMMUs, and each IOMMU is related
to IVHDs type 10h, 11h and 40h in the ACPI IVRS table.
- Always scan through the whole ivhd_hdrs list to find IVHDs that has
the same DeviceId but less prioritized IVHD type.
Sponsored by: The FreeBSD Foundation
MFC with: 74ada297e897
Reviewed by: grehan
Approved by: lwhsu (mentor)
Differential Revision: https://reviews.freebsd.org/D29525
(cherry picked from commit 6fe60f1d5c39c94fc87534e9dd4e9630594e0bec)
---
sys/amd64/vmm/amd/ivrs_drv.c | 47 ++++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/sys/amd64/vmm/amd/ivrs_drv.c b/sys/amd64/vmm/amd/ivrs_drv.c
index 430d18a059a2..68c31788e29d 100644
--- a/sys/amd64/vmm/amd/ivrs_drv.c
+++ b/sys/amd64/vmm/amd/ivrs_drv.c
@@ -57,7 +57,7 @@ int ivhd_count; /* Number of IVHD header. */
* Cached IVHD header list.
* Single entry for each IVHD, filtered the legacy one.
*/
-ACPI_IVRS_HARDWARE1 *ivhd_hdrs[10];
+ACPI_IVRS_HARDWARE1 **ivhd_hdrs;
extern int amdvi_ptp_level; /* Page table levels. */
@@ -134,9 +134,11 @@ ivrs_is_ivhd(UINT8 type)
static int
ivhd_count_iter(ACPI_IVRS_HEADER * ivrs_he, void *arg)
{
+ int *count;
+ count = (int *)arg;
if (ivrs_is_ivhd(ivrs_he->Type))
- ivhd_count++;
+ (*count)++;
return (1);
}
@@ -349,7 +351,7 @@ ivhd_identify(driver_t *driver, device_t parent)
ACPI_TABLE_IVRS *ivrs;
ACPI_IVRS_HARDWARE1 *ivhd;
ACPI_STATUS status;
- int i, count = 0;
+ int i, j, count = 0;
uint32_t ivrs_ivinfo;
if (acpi_disabled("ivhd"))
@@ -370,32 +372,35 @@ ivhd_identify(driver_t *driver, device_t parent)
REG_BITS(ivrs_ivinfo, 7, 5), REG_BITS(ivrs_ivinfo, 22, 22),
"\020\001EFRSup");
- ivrs_hdr_iterate_tbl(ivhd_count_iter, NULL);
- if (!ivhd_count)
+ ivrs_hdr_iterate_tbl(ivhd_count_iter, &count);
+ if (!count)
return;
- for (i = 0; i < ivhd_count; i++) {
+ ivhd_hdrs = malloc(sizeof(void *) * count, M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ for (i = 0; i < count; i++) {
ivhd = ivhd_find_by_index(i);
KASSERT(ivhd, ("ivhd%d is NULL\n", i));
- ivhd_hdrs[i] = ivhd;
- }
- /*
- * Scan for presence of legacy and non-legacy device type
- * for same AMD-Vi device and override the old one.
- */
- for (i = ivhd_count - 1 ; i > 0 ; i--){
- if (ivhd_is_newer(&ivhd_hdrs[i-1]->Header,
- &ivhd_hdrs[i]->Header)) {
- memmove(&ivhd_hdrs[i-1], &ivhd_hdrs[i],
- sizeof(void *) * (ivhd_count - i));
- ivhd_count--;
+ /*
+ * Scan for presence of legacy and non-legacy device type
+ * for same IOMMU device and override the old one.
+ *
+ * If there is no existing IVHD to the same IOMMU device,
+ * the IVHD header pointer is appended.
+ */
+ for (j = 0; j < ivhd_count; j++) {
+ if (ivhd_is_newer(&ivhd_hdrs[j]->Header, &ivhd->Header))
+ break;
}
+ ivhd_hdrs[j] = ivhd;
+ if (j == ivhd_count)
+ ivhd_count++;
}
ivhd_devs = malloc(sizeof(device_t) * ivhd_count, M_DEVBUF,
M_WAITOK | M_ZERO);
- for (i = 0; i < ivhd_count; i++) {
+ for (i = 0, j = 0; i < ivhd_count; i++) {
ivhd = ivhd_hdrs[i];
KASSERT(ivhd, ("ivhd%d is NULL\n", i));
@@ -417,13 +422,13 @@ ivhd_identify(driver_t *driver, device_t parent)
break;
}
}
- count++;
+ j++;
}
/*
* Update device count in case failed to attach.
*/
- ivhd_count = count;
+ ivhd_count = j;
}
static int
More information about the dev-commits-src-all
mailing list