hv: Remove redundant get_dmar_info API calls

get_dmar_info API is called from multiple functions in vtd.c. This patch
calls get_dmar_info once during init and uses the cached info during
runtime.

Tracked-On: #2657
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Sainath Grandhi 2019-02-26 17:41:03 -08:00 committed by Xie, Nanlin
parent 308d4e8c4e
commit b49df10a23
3 changed files with 65 additions and 74 deletions

View File

@ -208,6 +208,7 @@ static struct dmar_drhd_rt dmar_drhd_units[CONFIG_MAX_IOMMU_NUM];
static bool iommu_page_walk_coherent = true;
static struct iommu_domain *fallback_iommu_domain;
static uint32_t qi_status = 0U;
static struct dmar_info *platform_dmar_info = NULL;
/* Domain id 0 is reserved in some cases per VT-d */
#define MAX_DOMAIN_NUM (CONFIG_MAX_VM_NUM + 1)
@ -221,30 +222,20 @@ static int32_t dmar_register_hrhd(struct dmar_drhd_rt *dmar_unit);
static struct dmar_drhd_rt *device_to_dmaru(uint16_t segment, uint8_t bus, uint8_t devfun);
static int32_t register_hrhd_units(void)
{
struct dmar_info *info = get_dmar_info();
struct dmar_drhd_rt *drhd_rt;
uint32_t i;
int32_t ret = 0;
if ((info == NULL) || (info->drhd_count == 0U)) {
pr_fatal("%s: can't find dmar info\n", __func__);
ret = -ENODEV;
} else if (info->drhd_count > CONFIG_MAX_IOMMU_NUM) {
pr_fatal("%s: dmar count(%d) beyond the limitation(%d)\n",
__func__, info->drhd_count, CONFIG_MAX_IOMMU_NUM);
ret = -EINVAL;
} else {
for (i = 0U; i < info->drhd_count; i++) {
for (i = 0U; i < platform_dmar_info->drhd_count; i++) {
drhd_rt = &dmar_drhd_units[i];
drhd_rt->index = i;
drhd_rt->drhd = &info->drhd_units[i];
drhd_rt->drhd = &platform_dmar_info->drhd_units[i];
drhd_rt->dmar_irq = IRQ_INVALID;
ret = dmar_register_hrhd(drhd_rt);
if (ret != 0) {
break;
}
}
}
return ret;
}
@ -544,15 +535,11 @@ static int32_t dmar_register_hrhd(struct dmar_drhd_rt *dmar_unit)
static struct dmar_drhd_rt *ioapic_to_dmaru(uint16_t ioapic_id, union pci_bdf *sid)
{
struct dmar_info *info = get_dmar_info();
struct dmar_drhd_rt *dmar_unit = NULL;
uint32_t i, j;
bool found = false;
if (info == NULL) {
pr_fatal("%s: can't find dmar info\n", __func__);
} else {
for (j = 0U; j < info->drhd_count; j++) {
for (j = 0U; j < platform_dmar_info->drhd_count; j++) {
dmar_unit = &dmar_drhd_units[j];
for (i = 0U; i < dmar_unit->drhd->dev_cnt; i++) {
if ((dmar_unit->drhd->devices[i].type == ACPI_DMAR_SCOPE_TYPE_IOAPIC) &&
@ -569,24 +556,19 @@ static struct dmar_drhd_rt *ioapic_to_dmaru(uint16_t ioapic_id, union pci_bdf *s
}
}
if (j == info->drhd_count) {
if (j == platform_dmar_info->drhd_count) {
dmar_unit = NULL;
}
}
return dmar_unit;
}
static struct dmar_drhd_rt *device_to_dmaru(uint16_t segment, uint8_t bus, uint8_t devfun)
{
struct dmar_info *info = get_dmar_info();
struct dmar_drhd_rt *dmar_unit = NULL;
uint32_t i, j;
if (info == NULL) {
pr_fatal("%s: can't find dmar info\n", __func__);
} else {
for (j = 0U; j < info->drhd_count; j++) {
for (j = 0U; j < platform_dmar_info->drhd_count; j++) {
dmar_unit = &dmar_drhd_units[j];
if (dmar_unit->drhd->segment != segment) {
@ -607,10 +589,9 @@ static struct dmar_drhd_rt *device_to_dmaru(uint16_t segment, uint8_t bus, uint8
}
/* not found */
if (j == info->drhd_count) {
if (j == platform_dmar_info->drhd_count) {
dmar_unit = NULL;
}
}
return dmar_unit;
}
@ -1229,12 +1210,10 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s
*/
static void do_action_for_iommus(void (*action)(struct dmar_drhd_rt *))
{
struct dmar_info *info = get_dmar_info();
struct dmar_drhd_rt *dmar_unit;
uint32_t i;
if (info != NULL) {
for (i = 0U; i < info->drhd_count; i++) {
for (i = 0U; i < platform_dmar_info->drhd_count; i++) {
dmar_unit = &dmar_drhd_units[i];
if (!dmar_unit->drhd->ignore) {
action(dmar_unit);
@ -1242,9 +1221,6 @@ static void do_action_for_iommus(void (*action)(struct dmar_drhd_rt *))
dev_dbg(ACRN_DBG_IOMMU, "ignore dmar_unit @0x%x", dmar_unit->drhd->reg_base_addr);
}
}
} else {
pr_fatal("%s: can't find dmar info\n", __func__);
}
}
struct iommu_domain *create_iommu_domain(uint16_t vm_id, uint64_t translation_table, uint32_t addr_width)
@ -1351,11 +1327,21 @@ int32_t init_iommu(void)
{
int32_t ret = 0;
platform_dmar_info = get_dmar_info();
if ((platform_dmar_info == NULL) || (platform_dmar_info->drhd_count == 0U)) {
pr_fatal("%s: can't find dmar info\n", __func__);
ret = -ENODEV;
} else if (platform_dmar_info->drhd_count > CONFIG_MAX_IOMMU_NUM) {
pr_fatal("%s: dmar count(%d) beyond the limitation(%d)\n",
__func__, platform_dmar_info->drhd_count, CONFIG_MAX_IOMMU_NUM);
ret = -EINVAL;
} else {
ret = register_hrhd_units();
if (ret == 0) {
do_action_for_iommus(dmar_prepare);
}
}
return ret;
}

View File

@ -306,6 +306,7 @@ static int32_t parse_dmar_table(void)
/**
* @post return != NULL
* @post return->drhd_count > 0U
*/
struct dmar_info *get_dmar_info(void)
{

View File

@ -130,6 +130,10 @@ static struct dmar_info sbl_dmar_info = {
.drhd_units = drhd_info_array,
};
/**
* @post return != NULL
* @post return->drhd_count > 0U
*/
struct dmar_info *get_dmar_info(void)
{
return &sbl_dmar_info;