mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 04:33:55 +00:00
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>
This commit is contained in:
parent
93386d3c70
commit
74023a9a75
@ -1155,6 +1155,9 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
|
|||||||
if (dmar_unit == NULL) {
|
if (dmar_unit == NULL) {
|
||||||
pr_err("no dmar unit found for device: %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
pr_err("no dmar unit found for device: %x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
} else if (dmar_unit->drhd->ignore) {
|
||||||
|
dev_dbg(ACRN_DBG_IOMMU, "device is ignored :0x%x:%x.%x", bus, pci_slot(devfun), pci_func(devfun));
|
||||||
|
ret = -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
root_table = (struct dmar_entry *)hpa2hva(dmar_unit->root_table_addr);
|
root_table = (struct dmar_entry *)hpa2hva(dmar_unit->root_table_addr);
|
||||||
root_entry = root_table + bus;
|
root_entry = root_table + bus;
|
||||||
@ -1257,15 +1260,20 @@ void destroy_iommu_domain(struct iommu_domain *domain)
|
|||||||
int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
|
int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
|
||||||
{
|
{
|
||||||
int32_t status = 0;
|
int32_t status = 0;
|
||||||
|
uint16_t bus_local = bus;
|
||||||
|
|
||||||
/* TODO: check if the device assigned */
|
/* TODO: check if the device assigned */
|
||||||
|
|
||||||
if (fallback_iommu_domain != NULL) {
|
if (bus_local < CONFIG_IOMMU_BUS_NUM) {
|
||||||
status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
|
if (fallback_iommu_domain != NULL) {
|
||||||
}
|
status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
|
||||||
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
status = add_iommu_device(domain, 0U, bus, devfun);
|
status = add_iommu_device(domain, 0U, bus, devfun);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -1274,12 +1282,18 @@ int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t de
|
|||||||
int32_t unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
|
int32_t unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, uint8_t devfun)
|
||||||
{
|
{
|
||||||
int32_t status = 0;
|
int32_t status = 0;
|
||||||
|
uint16_t bus_local = bus;
|
||||||
|
|
||||||
/* TODO: check if the device assigned */
|
/* TODO: check if the device assigned */
|
||||||
status = remove_iommu_device(domain, 0U, bus, devfun);
|
|
||||||
|
|
||||||
if ((status == 0) && (fallback_iommu_domain != NULL)) {
|
if (bus_local < CONFIG_IOMMU_BUS_NUM) {
|
||||||
status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
|
status = remove_iommu_device(domain, 0U, bus, devfun);
|
||||||
|
|
||||||
|
if ((status == 0) && (fallback_iommu_domain != NULL)) {
|
||||||
|
status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
Loading…
Reference in New Issue
Block a user