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 <arindam.roy@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Arindam Roy 2019-01-25 14:18:55 -08:00 committed by wenlingz
parent 24cf377d5d
commit de8d85753e
13 changed files with 49 additions and 39 deletions

View File

@ -306,7 +306,7 @@ deinitialization:
.. doxygenfunction:: init_iommu .. doxygenfunction:: init_iommu
:project: Project ACRN :project: Project ACRN
.. doxygenfunction:: init_iommu_sos_vm_domain .. doxygenfunction:: init_fallback_iommu_domain
:project: Project ACRN :project: Project ACRN
runtime runtime

View File

@ -6,6 +6,7 @@
#include <hypervisor.h> #include <hypervisor.h>
#include <ioapic.h> #include <ioapic.h>
#include <vtd.h>
/* /*
* lookup a ptdev entry by sid * lookup a ptdev entry by sid

View File

@ -9,6 +9,7 @@
#include <hypervisor.h> #include <hypervisor.h>
#include <cpu.h> #include <cpu.h>
#include <virtual_cr.h> #include <virtual_cr.h>
#include <vtd.h>
/* CR0 bits hv want to trap to track status change */ /* CR0 bits hv want to trap to track status change */
#define CR0_TRAP_MASK (CR0_PE | CR0_PG | CR0_WP | CR0_CD | CR0_NW) #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 * disabled behavior
*/ */
exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, PAT_ALL_UC_VALUE); 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(); cache_flush_invalidate_all();
} }
} else { } else {

View File

@ -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); status = init_vm_boot_info(vm);
if (status == 0) { if (status == 0) {
init_iommu_sos_vm_domain(vm); init_fallback_iommu_domain(vm->iommu, vm->vm_id, vm->arch_vm.nworld_eptp);
} else { } else {
need_cleanup = true; need_cleanup = true;
} }

View File

@ -6,6 +6,7 @@
#include <hypervisor.h> #include <hypervisor.h>
#include <virtual_cr.h> #include <virtual_cr.h>
#include <vtd.h>
/* /*
* According to "SDM APPENDIX C VMX BASIC EXIT REASONS", * 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) 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(); cache_flush_invalidate_all();
} }

View File

@ -7,6 +7,7 @@
#include <init.h> #include <init.h>
#include <hypervisor.h> #include <hypervisor.h>
#include <schedule.h> #include <schedule.h>
#include <vtd.h>
/* Push sp magic to top of stack for call trace */ /* Push sp magic to top of stack for call trace */
#define SWITCH_TO(rsp, to) \ #define SWITCH_TO(rsp, to) \

View File

@ -5,6 +5,7 @@
#include <hypervisor.h> #include <hypervisor.h>
#include <trampoline.h> #include <trampoline.h>
#include <ioapic.h> #include <ioapic.h>
#include <vtd.h>
struct cpu_context cpu_ctx; struct cpu_context cpu_ctx;

View File

@ -7,6 +7,7 @@
#define pr_prefix "iommu: " #define pr_prefix "iommu: "
#include <hypervisor.h> #include <hypervisor.h>
#include <vtd.h>
#define DBG_IOMMU 0 #define DBG_IOMMU 0
@ -146,15 +147,6 @@ struct dmar_qi_desc {
uint64_t upper; 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 context_table {
struct page buses[CONFIG_IOMMU_BUS_NUM]; 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; 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; bool ret;
if ((vm->iommu == NULL) || (vm->iommu->iommu_snoop)) { if ((iommu == NULL) || (iommu->iommu_snoop)) {
ret = true; ret = true;
} else { } else {
ret = false; 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 struct dmar_drhd_rt dmar_drhd_units[CONFIG_MAX_IOMMU_NUM];
static bool iommu_page_walk_coherent = true; 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; static uint32_t qi_status = 0U;
/* Domain id 0 is reserved in some cases per VT-d */ /* 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 */ /* TODO: check if the device assigned */
if (sos_vm_domain != NULL) { if (fallback_iommu_domain != NULL) {
status = remove_iommu_device(sos_vm_domain, 0U, bus, devfun); status = remove_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
} }
if (status == 0) { 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 */ /* TODO: check if the device assigned */
status = remove_iommu_device(domain, 0U, bus, devfun); status = remove_iommu_device(domain, 0U, bus, devfun);
if ((status == 0) && (sos_vm_domain != NULL)) { if ((status == 0) && (fallback_iommu_domain != NULL)) {
status = add_iommu_device(sos_vm_domain, 0U, bus, devfun); status = add_iommu_device(fallback_iommu_domain, 0U, bus, devfun);
} }
return status; return status;
@ -1362,22 +1354,22 @@ int32_t init_iommu(void)
return ret; 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 bus;
uint16_t devfun; 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; fallback_iommu_domain = (struct iommu_domain *) iommu_dmn;
if (sos_vm_domain == NULL) { if (fallback_iommu_domain == NULL) {
pr_err("sos_vm domain is NULL\n"); pr_err("fallback_iommu_domain is NULL\n");
} else { } else {
for (bus = 0U; bus < CONFIG_IOMMU_BUS_NUM; bus++) { for (bus = 0U; bus < CONFIG_IOMMU_BUS_NUM; bus++) {
for (devfun = 0U; devfun <= 255U; devfun++) { for (devfun = 0U; devfun <= 255U; devfun++) {
if (add_iommu_device(sos_vm_domain, 0U, (uint8_t)bus, (uint8_t)devfun) != 0) { if (add_iommu_device(fallback_iommu_domain, 0U, (uint8_t)bus, (uint8_t)devfun) != 0) {
/* the panic only occurs before SOS_VM starts running in sharing mode */ /* the panic only occurs before fallback_iommu_domain starts running in sharing mode */
panic("Failed to add %x:%x.%x to SOS_VM domain", bus, pci_slot(devfun), pci_func(devfun)); panic("Failed to add %x:%x.%x to fallback_iommu_domain domain", bus, pci_slot(devfun), pci_func(devfun));
} }
} }
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <hypervisor.h> #include <hypervisor.h>
#include <vtd.h>
#ifndef CONFIG_DMAR_PARSE_ENABLED #ifndef CONFIG_DMAR_PARSE_ENABLED

View File

@ -9,6 +9,7 @@
#include <hypercall.h> #include <hypercall.h>
#include <version.h> #include <version.h>
#include <reloc.h> #include <reloc.h>
#include <vtd.h>
#define ACRN_DBG_HYCALL 6U #define ACRN_DBG_HYCALL 6U

View File

@ -30,6 +30,7 @@
/* Passthrough PCI device related operations */ /* Passthrough PCI device related operations */
#include <hypervisor.h> #include <hypervisor.h>
#include <vtd.h>
#include "pci_priv.h" #include "pci_priv.h"
static inline uint32_t pci_bar_base(uint32_t bar) static inline uint32_t pci_bar_base(uint32_t bar)

View File

@ -38,7 +38,6 @@
#include <vmx.h> #include <vmx.h>
#include <vmcs.h> #include <vmcs.h>
#include <assign.h> #include <assign.h>
#include <vtd.h>
#include <guest_memory.h> #include <guest_memory.h>
#include <vmexit.h> #include <vmexit.h>

View File

@ -47,6 +47,15 @@ enum acpi_dmar_scope_type {
ACPI_DMAR_SCOPE_TYPE_RESERVED = 6 /* 6 and greater are reserved */ 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) static inline uint8_t dmar_ver_major(uint64_t version)
{ {
return (((uint8_t)version & 0xf0U) >> 4U); 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. * @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] domain iommu domain the device is assigned to
* @param[in] bus the 8-bit bus number of the device * @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 . * @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] domain iommu domain the device is assigned to
* @param[in] bus the 8-bit bus number of the device * @param[in] bus the 8-bit bus number of the device
@ -641,30 +650,32 @@ void resume_iommu(void);
int32_t init_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. * 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 SOS_VM domain when creating it. * 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. * @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. * @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 true support
* @retval false not 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. * @brief Assign RTE for Interrupt Remapping Table.