From de8d85753eff73ce30bd4c5f8d98438b1a667696 Mon Sep 17 00:00:00 2001 From: Arindam Roy Date: Fri, 25 Jan 2019 14:18:55 -0800 Subject: [PATCH] HV: Modularize vtd.c to remove acrn_vm usage This patch is a modified one. It removes the usage of acrn_vm struct from inside vtd.c. It also puts struct iommu_domain inside vtd.h, from vtd.c. It modifies the signature of init_iommu_domain in order to remove dependency on acrn_vm from inside vtd.c. Incorporated comments from Jason and Eddie. Changed the name of sos_vm_domain to fallback_iommu_domain Removed any reference of sos_vm from vtd.[c|h] files, including comments. Tracked-On: #2496 Signed-off-by: Arindam Roy Reviewed-by: Jason Chen CJ --- doc/developer-guides/hld/hv-vt-d.rst | 2 +- hypervisor/arch/x86/guest/assign.c | 1 + hypervisor/arch/x86/guest/virtual_cr.c | 3 +- hypervisor/arch/x86/guest/vm.c | 2 +- hypervisor/arch/x86/guest/vmexit.c | 3 +- hypervisor/arch/x86/init.c | 1 + hypervisor/arch/x86/pm.c | 1 + hypervisor/arch/x86/vtd.c | 40 +++++++++++--------------- hypervisor/bsp/sbl/const_dmar.c | 1 + hypervisor/common/hypercall.c | 1 + hypervisor/dm/vpci/pci_pt.c | 1 + hypervisor/include/arch/x86/hv_arch.h | 1 - hypervisor/include/arch/x86/vtd.h | 31 +++++++++++++------- 13 files changed, 49 insertions(+), 39 deletions(-) diff --git a/doc/developer-guides/hld/hv-vt-d.rst b/doc/developer-guides/hld/hv-vt-d.rst index 56f95d17b..0476aeb29 100644 --- a/doc/developer-guides/hld/hv-vt-d.rst +++ b/doc/developer-guides/hld/hv-vt-d.rst @@ -306,7 +306,7 @@ deinitialization: .. doxygenfunction:: init_iommu :project: Project ACRN -.. doxygenfunction:: init_iommu_sos_vm_domain +.. doxygenfunction:: init_fallback_iommu_domain :project: Project ACRN runtime diff --git a/hypervisor/arch/x86/guest/assign.c b/hypervisor/arch/x86/guest/assign.c index 3cd67ebfa..fe75550b7 100644 --- a/hypervisor/arch/x86/guest/assign.c +++ b/hypervisor/arch/x86/guest/assign.c @@ -6,6 +6,7 @@ #include #include +#include /* * lookup a ptdev entry by sid diff --git a/hypervisor/arch/x86/guest/virtual_cr.c b/hypervisor/arch/x86/guest/virtual_cr.c index a87699db9..1301a7191 100644 --- a/hypervisor/arch/x86/guest/virtual_cr.c +++ b/hypervisor/arch/x86/guest/virtual_cr.c @@ -9,6 +9,7 @@ #include #include #include +#include /* CR0 bits hv want to trap to track status change */ #define CR0_TRAP_MASK (CR0_PE | CR0_PG | CR0_WP | CR0_CD | CR0_NW) @@ -160,7 +161,7 @@ static void vmx_write_cr0(struct acrn_vcpu *vcpu, uint64_t cr0) * disabled behavior */ exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, PAT_ALL_UC_VALUE); - if (!iommu_snoop_supported(vcpu->vm)) { + if (!iommu_snoop_supported(vcpu->vm->iommu)) { cache_flush_invalidate_all(); } } else { diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 08432b43e..89433937a 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -286,7 +286,7 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_ status = init_vm_boot_info(vm); if (status == 0) { - init_iommu_sos_vm_domain(vm); + init_fallback_iommu_domain(vm->iommu, vm->vm_id, vm->arch_vm.nworld_eptp); } else { need_cleanup = true; } diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index 331380a7e..cc39eec3c 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -6,6 +6,7 @@ #include #include +#include /* * According to "SDM APPENDIX C VMX BASIC EXIT REASONS", @@ -306,7 +307,7 @@ static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu) static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu) { - if (!iommu_snoop_supported(vcpu->vm)) { + if (!iommu_snoop_supported(vcpu->vm->iommu)) { cache_flush_invalidate_all(); } diff --git a/hypervisor/arch/x86/init.c b/hypervisor/arch/x86/init.c index 5a94b7874..ae5ec95cb 100644 --- a/hypervisor/arch/x86/init.c +++ b/hypervisor/arch/x86/init.c @@ -7,6 +7,7 @@ #include #include #include +#include /* Push sp magic to top of stack for call trace */ #define SWITCH_TO(rsp, to) \ diff --git a/hypervisor/arch/x86/pm.c b/hypervisor/arch/x86/pm.c index 279cc7e6f..4b0ddf05f 100644 --- a/hypervisor/arch/x86/pm.c +++ b/hypervisor/arch/x86/pm.c @@ -5,6 +5,7 @@ #include #include #include +#include struct cpu_context cpu_ctx; diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index c700703cc..2218010a6 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -7,6 +7,7 @@ #define pr_prefix "iommu: " #include +#include #define DBG_IOMMU 0 @@ -146,15 +147,6 @@ struct dmar_qi_desc { uint64_t upper; }; -struct iommu_domain { - bool is_host; - bool is_tt_ept; /* if reuse EPT of the domain */ - uint16_t vm_id; - uint32_t addr_width; /* address width of the domain */ - uint64_t trans_table_ptr; - bool iommu_snoop; -}; - struct context_table { struct page buses[CONFIG_IOMMU_BUS_NUM]; }; @@ -190,11 +182,11 @@ static inline uint8_t *get_ir_table(uint32_t dmar_index) return ir_tables[dmar_index].tables[0].contents; } -bool iommu_snoop_supported(const struct acrn_vm *vm) +bool iommu_snoop_supported(const struct iommu_domain *iommu) { bool ret; - if ((vm->iommu == NULL) || (vm->iommu->iommu_snoop)) { + if ((iommu == NULL) || (iommu->iommu_snoop)) { ret = true; } else { ret = false; @@ -205,7 +197,7 @@ bool iommu_snoop_supported(const struct acrn_vm *vm) static struct dmar_drhd_rt dmar_drhd_units[CONFIG_MAX_IOMMU_NUM]; static bool iommu_page_walk_coherent = true; -static struct iommu_domain *sos_vm_domain; +static struct iommu_domain *fallback_iommu_domain; static uint32_t qi_status = 0U; /* Domain id 0 is reserved in some cases per VT-d */ @@ -1302,8 +1294,8 @@ int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t de /* TODO: check if the device assigned */ - if (sos_vm_domain != NULL) { - status = remove_iommu_device(sos_vm_domain, 0U, bus, devfun); + if (fallback_iommu_domain != NULL) { + status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun); } if (status == 0) { @@ -1320,8 +1312,8 @@ int32_t unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, ui /* TODO: check if the device assigned */ status = remove_iommu_device(domain, 0U, bus, devfun); - if ((status == 0) && (sos_vm_domain != NULL)) { - status = add_iommu_device(sos_vm_domain, 0U, bus, devfun); + if ((status == 0) && (fallback_iommu_domain != NULL)) { + status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun); } return status; @@ -1362,22 +1354,22 @@ int32_t init_iommu(void) return ret; } -void init_iommu_sos_vm_domain(struct acrn_vm *sos_vm) +void init_fallback_iommu_domain(struct iommu_domain *iommu_dmn, uint16_t vm_id, void *eptp) { uint16_t bus; uint16_t devfun; - sos_vm->iommu = create_iommu_domain(sos_vm->vm_id, hva2hpa(sos_vm->arch_vm.nworld_eptp), 48U); + iommu_dmn = create_iommu_domain(vm_id, hva2hpa(eptp), 48U); - sos_vm_domain = (struct iommu_domain *) sos_vm->iommu; - if (sos_vm_domain == NULL) { - pr_err("sos_vm domain is NULL\n"); + fallback_iommu_domain = (struct iommu_domain *) iommu_dmn; + if (fallback_iommu_domain == NULL) { + pr_err("fallback_iommu_domain is NULL\n"); } else { for (bus = 0U; bus < CONFIG_IOMMU_BUS_NUM; bus++) { for (devfun = 0U; devfun <= 255U; devfun++) { - if (add_iommu_device(sos_vm_domain, 0U, (uint8_t)bus, (uint8_t)devfun) != 0) { - /* the panic only occurs before SOS_VM starts running in sharing mode */ - panic("Failed to add %x:%x.%x to SOS_VM domain", bus, pci_slot(devfun), pci_func(devfun)); + if (add_iommu_device(fallback_iommu_domain, 0U, (uint8_t)bus, (uint8_t)devfun) != 0) { + /* the panic only occurs before fallback_iommu_domain starts running in sharing mode */ + panic("Failed to add %x:%x.%x to fallback_iommu_domain domain", bus, pci_slot(devfun), pci_func(devfun)); } } } diff --git a/hypervisor/bsp/sbl/const_dmar.c b/hypervisor/bsp/sbl/const_dmar.c index 41c87b5ab..179e194c0 100644 --- a/hypervisor/bsp/sbl/const_dmar.c +++ b/hypervisor/bsp/sbl/const_dmar.c @@ -5,6 +5,7 @@ */ #include +#include #ifndef CONFIG_DMAR_PARSE_ENABLED diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index ca5866ea3..5ab924d16 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -9,6 +9,7 @@ #include #include #include +#include #define ACRN_DBG_HYCALL 6U diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index 5b580d900..930b24d96 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -30,6 +30,7 @@ /* Passthrough PCI device related operations */ #include +#include #include "pci_priv.h" static inline uint32_t pci_bar_base(uint32_t bar) diff --git a/hypervisor/include/arch/x86/hv_arch.h b/hypervisor/include/arch/x86/hv_arch.h index 237ac03e0..86408800e 100644 --- a/hypervisor/include/arch/x86/hv_arch.h +++ b/hypervisor/include/arch/x86/hv_arch.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/hypervisor/include/arch/x86/vtd.h b/hypervisor/include/arch/x86/vtd.h index 87a2f19a5..01212248a 100644 --- a/hypervisor/include/arch/x86/vtd.h +++ b/hypervisor/include/arch/x86/vtd.h @@ -47,6 +47,15 @@ enum acpi_dmar_scope_type { ACPI_DMAR_SCOPE_TYPE_RESERVED = 6 /* 6 and greater are reserved */ }; +struct iommu_domain { + bool is_host; + bool is_tt_ept; /* if reuse EPT of the domain */ + uint16_t vm_id; + uint32_t addr_width; /* address width of the domain */ + uint64_t trans_table_ptr; + bool iommu_snoop; +}; + static inline uint8_t dmar_ver_major(uint64_t version) { return (((uint8_t)version & 0xf0U) >> 4U); @@ -532,7 +541,7 @@ struct iommu_domain; /** * @brief Assign a device specified by bus & devfun to a iommu domain. * - * Remove the device from the SOS_VM domain (if present), and add it to the specific domain. + * Remove the device from the fallback iommu domain (if present), and add it to the specific domain. * * @param[in] domain iommu domain the device is assigned to * @param[in] bus the 8-bit bus number of the device @@ -549,7 +558,7 @@ int32_t assign_iommu_device(struct iommu_domain *domain, uint8_t bus, uint8_t de /** * @brief Unassign a device specified by bus & devfun from a iommu domain . * - * Remove the device from the specific domain, and then add it to the SOS_VM domain (if present). + * Remove the device from the specific domain, and then add it to the fallback iommu domain (if present). * * @param[in] domain iommu domain the device is assigned to * @param[in] bus the 8-bit bus number of the device @@ -641,30 +650,32 @@ void resume_iommu(void); int32_t init_iommu(void); /** - * @brief Init SOS_VM domain of iommu. + * @brief Init fallback iommu domain of iommu. * - * Create SOS_VM domain using the Normal World's EPT table of SOS_VM as address translation table. - * All PCI devices are added to the SOS_VM domain when creating it. + * Create fallback iommu domain using the Normal World's EPT table of fallback iommu as address translation table. + * All PCI devices are added to the fallback iommu domain when creating it. * - * @param[in] sos_vm pointer to SOS_VM + * @param[in] iommu_dmn pointer to fallback iommu domain + * @param[in] vm_id ID of the VM for which iommu_domain needs to be created + * @param[in] eptp EPT hieararchy table * - * @pre sos_vm shall point to SOS_VM + * @pre iommu shall point to fallback iommu domain * * @remark to reduce boot time & memory cost, a config IOMMU_INIT_BUS_LIMIT, which limit the bus number. * */ -void init_iommu_sos_vm_domain(struct acrn_vm *sos_vm); +void init_fallback_iommu_domain(struct iommu_domain *iommu_dmn, uint16_t vm_id, void *eptp); /** * @brief check the iommu if support cache snoop. * - * @param[in] vm pointer to VM to check + * @param[in] iommu pointer to iommu domain to check * * @retval true support * @retval false not support * */ -bool iommu_snoop_supported(const struct acrn_vm *vm); +bool iommu_snoop_supported(const struct iommu_domain *iommu); /** * @brief Assign RTE for Interrupt Remapping Table.