Skip to content

Commit 74023a9

Browse files
binbinwu1wenlingz
authored andcommitted
hv: vtd: check bus number when assign/unassign device
Input parameter "bus" of assign_iommu_device/unassign_iommu_device may be from hypercall. And the conext tables are static allocated according to CONFIG_IOMMU_BUS_NUM. Need to check the bus value to avoid access invalid memory address with invalid value. Tracked-On: #2743 Signed-off-by: Binbin Wu <binbin.wu@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 93386d3 commit 74023a9

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

hypervisor/arch/x86/vtd.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,9 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
11551155
if (dmar_unit == NULL) {
11561156
pr_err("no dmar unit found for device: %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
11571157
ret = -EINVAL;
1158+
} else if (dmar_unit->drhd->ignore) {
1159+
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
1160+
ret = -EINVAL;
11581161
} else {
11591162
root_table = (struct dmar_entry *)hpa2hva(dmar_unit->root_table_addr);
11601163
root_entry = root_table + bus;
@@ -1257,15 +1260,20 @@ void destroy_iommu_domain(struct iommu_domain *domain)
12571260
int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
12581261
{
12591262
int32_t status = 0;
1263+
uint16_t bus_local = bus;
12601264

12611265
/* TODO: check if the device assigned */
12621266

1263-
if (fallback_iommu_domain != NULL) {
1264-
status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
1265-
}
1267+
if (bus_local < CONFIG_IOMMU_BUS_NUM) {
1268+
if (fallback_iommu_domain != NULL) {
1269+
status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
1270+
}
12661271

1267-
if (status == 0) {
1268-
status = add_iommu_device(domain, 0U, bus, devfun);
1272+
if (status == 0) {
1273+
status = add_iommu_device(domain, 0U, bus, devfun);
1274+
}
1275+
} else {
1276+
status = -EINVAL;
12691277
}
12701278

12711279
return status;
@@ -1274,12 +1282,18 @@ int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t de
12741282
int32_t unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
12751283
{
12761284
int32_t status = 0;
1285+
uint16_t bus_local = bus;
12771286

12781287
/* TODO: check if the device assigned */
1279-
status = remove_iommu_device(domain, 0U, bus, devfun);
12801288

1281-
if ((status == 0) && (fallback_iommu_domain != NULL)) {
1282-
status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
1289+
if (bus_local < CONFIG_IOMMU_BUS_NUM) {
1290+
status = remove_iommu_device(domain, 0U, bus, devfun);
1291+
1292+
if ((status == 0) && (fallback_iommu_domain != NULL)) {
1293+
status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
1294+
}
1295+
} else {
1296+
status = -EINVAL;
12831297
}
12841298

12851299
return status;

0 commit comments

Comments
 (0)