From a2cb9c2b6a7f7d84b3e9a6e6a848045ed6df3d31 Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Thu, 8 Nov 2018 14:42:53 +0800 Subject: [PATCH] hv: vtd: add do_action_for_iommus Add an internal API to do action according to action function provided, which can simplify the code. Tracked-On: #1855 Signed-off-by: Binbin Wu Reviewed-by: Eddie Dong --- hypervisor/arch/x86/vtd.c | 134 +++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 74 deletions(-) diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index cf9b69e58..145022946 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -796,6 +796,43 @@ static void dmar_disable(struct dmar_drhd_rt *dmar_unit) dmar_fault_event_mask(dmar_unit); } +static void dmar_suspend(struct dmar_drhd_rt *dmar_unit) +{ + uint32_t i; + + /* flush */ + dmar_write_buffer_flush(dmar_unit); + dmar_invalid_context_cache_global(dmar_unit); + dmar_invalid_iotlb_global(dmar_unit); + + /* save IOMMU fault register state */ + for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) { + dmar_unit->fault_state[i] = iommu_read32(dmar_unit, DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE)); + } + /* disable translation */ + dmar_disable_translation(dmar_unit); +} + +static void dmar_resume(struct dmar_drhd_rt *dmar_unit) +{ + uint32_t i; + + /* set root table */ + dmar_set_root_table(dmar_unit); + + /* flush */ + dmar_write_buffer_flush(dmar_unit); + dmar_invalid_context_cache_global(dmar_unit); + dmar_invalid_iotlb_global(dmar_unit); + + /* restore IOMMU fault register state */ + for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) { + iommu_write32(dmar_unit, DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE), dmar_unit->fault_state[i]); + } + /* enable translation */ + dmar_enable_translation(dmar_unit); +} + static int add_iommu_device(struct iommu_domain *domain, uint16_t segment, uint8_t bus, uint8_t devfun) { struct dmar_drhd_rt *dmar_unit; @@ -949,6 +986,25 @@ static int remove_iommu_device(const struct iommu_domain *domain, uint16_t segme return 0; } +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 (action == NULL) + return; + + for (i = 0U; i < info->drhd_count; i++) { + dmar_unit = &dmar_drhd_units[i]; + if (!dmar_unit->drhd->ignore) { + action(dmar_unit); + } else { + dev_dbg(ACRN_DBG_IOMMU, "ignore dmar_unit @0x%x", dmar_unit->drhd->reg_base_addr); + } + } +} + struct iommu_domain *create_iommu_domain(uint16_t vm_id, uint64_t translation_table, uint32_t addr_width) { struct iommu_domain *domain; @@ -1021,92 +1077,22 @@ int unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, uint8_ void enable_iommu(void) { - struct dmar_info *info = get_dmar_info(); - struct dmar_drhd_rt *dmar_unit; - uint32_t j; - - for (j = 0U; j < info->drhd_count; j++) { - dmar_unit = &dmar_drhd_units[j]; - if (!dmar_unit->drhd->ignore) { - dmar_enable(dmar_unit); - } - else { - dev_dbg(ACRN_DBG_IOMMU, "ignore dmar_unit @0x%x", dmar_unit->drhd->reg_base_addr); - } - } + do_action_for_iommus(dmar_enable); } void disable_iommu(void) { - struct dmar_info *info = get_dmar_info(); - struct dmar_drhd_rt *dmar_unit; - uint32_t j; - - for (j = 0U; j < info->drhd_count; j++) { - dmar_unit = &dmar_drhd_units[j]; - dmar_disable(dmar_unit); - } + do_action_for_iommus(dmar_disable); } void suspend_iommu(void) { - struct dmar_info *info = get_dmar_info(); - struct dmar_drhd_rt *dmar_unit; - uint32_t i, j; - - for (j = 0U; j < info->drhd_count; j++) { - dmar_unit = &dmar_drhd_units[j]; - - if (dmar_unit->drhd->ignore) { - continue; - } - - /* flush */ - dmar_write_buffer_flush(dmar_unit); - dmar_invalid_context_cache_global(dmar_unit); - dmar_invalid_iotlb_global(dmar_unit); - - /* save IOMMU fault register state */ - for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) { - dmar_unit->fault_state[i] = iommu_read32(dmar_unit, - DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE)); - - } - /* disable translation */ - dmar_disable_translation(dmar_unit); - } + do_action_for_iommus(dmar_suspend); } void resume_iommu(void) { - struct dmar_drhd_rt *dmar_unit; - struct dmar_info *info = get_dmar_info(); - uint32_t i, j; - - /* restore IOMMU fault register state */ - for (j = 0U; j < info->drhd_count; j++) { - dmar_unit = &dmar_drhd_units[j]; - - if (dmar_unit->drhd->ignore) { - continue; - } - - /* set root table */ - dmar_set_root_table(dmar_unit); - - /* flush */ - dmar_write_buffer_flush(dmar_unit); - dmar_invalid_context_cache_global(dmar_unit); - dmar_invalid_iotlb_global(dmar_unit); - - /* restore IOMMU fault register state */ - for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) { - iommu_write32(dmar_unit, DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE), - dmar_unit->fault_state[i]); - } - /* enable translation */ - dmar_enable_translation(dmar_unit); - } + do_action_for_iommus(dmar_resume); } int init_iommu(void)