diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index 10ea0a013..bd3f6652b 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -1351,18 +1351,37 @@ int32_t dmar_assign_irte(const struct intr_source *intr_src, union dmar_ir_entry ret = -EINVAL; } else { dmar_enable_intr_remapping(dmar_unit); - irte->bits.remap.svt = 0x1UL; - irte->bits.remap.sq = 0x0UL; - irte->bits.remap.sid = sid.value; - irte->bits.remap.present = 0x1UL; - irte->bits.remap.mode = 0x0UL; - irte->bits.remap.trigger_mode = trigger_mode; - irte->bits.remap.fpd = 0x0UL; + ir_table = (union dmar_ir_entry *)hpa2hva(dmar_unit->ir_table_addr); ir_entry = ir_table + index; - ir_entry->value.hi_64 = irte->value.hi_64; - ir_entry->value.lo_64 = irte->value.lo_64; + if (intr_src->pid_paddr != 0UL) { + union dmar_ir_entry irte_pi; + + /* irte is in remapped mode format, convert to posted mode format */ + irte_pi.value.lo_64 = 0UL; + irte_pi.value.hi_64 = 0UL; + + irte_pi.bits.post.vector = irte->bits.remap.vector; + + irte_pi.bits.post.svt = 0x1UL; + irte_pi.bits.post.sid = sid.value; + irte_pi.bits.post.present = 0x1UL; + irte_pi.bits.post.mode = 0x1UL; + + irte_pi.bits.post.pda_l = (intr_src->pid_paddr) >> 6U; + irte_pi.bits.post.pda_h = (intr_src->pid_paddr) >> 32U; + + *ir_entry = irte_pi; + } else { + /* Fields that have not been initialized explicitly default to 0 */ + irte->bits.remap.svt = 0x1UL; + irte->bits.remap.sid = sid.value; + irte->bits.remap.present = 0x1UL; + irte->bits.remap.trigger_mode = trigger_mode; + + *ir_entry = *irte; + } iommu_flush_cache(ir_entry, sizeof(union dmar_ir_entry)); dmar_invalid_iec(dmar_unit, index, 0U, false); }