mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 04:33:55 +00:00
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 <binbin.wu@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
32ed3d1a76
commit
a2cb9c2b6a
@ -796,6 +796,43 @@ static void dmar_disable(struct dmar_drhd_rt *dmar_unit)
|
|||||||
dmar_fault_event_mask(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)
|
static int add_iommu_device(struct iommu_domain *domain, uint16_t segment, uint8_t bus, uint8_t devfun)
|
||||||
{
|
{
|
||||||
struct dmar_drhd_rt *dmar_unit;
|
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;
|
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 *create_iommu_domain(uint16_t vm_id, uint64_t translation_table, uint32_t addr_width)
|
||||||
{
|
{
|
||||||
struct iommu_domain *domain;
|
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)
|
void enable_iommu(void)
|
||||||
{
|
{
|
||||||
struct dmar_info *info = get_dmar_info();
|
do_action_for_iommus(dmar_enable);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_iommu(void)
|
void disable_iommu(void)
|
||||||
{
|
{
|
||||||
struct dmar_info *info = get_dmar_info();
|
do_action_for_iommus(dmar_disable);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void suspend_iommu(void)
|
void suspend_iommu(void)
|
||||||
{
|
{
|
||||||
struct dmar_info *info = get_dmar_info();
|
do_action_for_iommus(dmar_suspend);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resume_iommu(void)
|
void resume_iommu(void)
|
||||||
{
|
{
|
||||||
struct dmar_drhd_rt *dmar_unit;
|
do_action_for_iommus(dmar_resume);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_iommu(void)
|
int init_iommu(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user