hv: enable VT-d PI for ptdev if intr_src->pid_addr is non-zero
Fill in posted interrupt fields (vector, pda, etc) and set mode to 1 to
enable VT-d PI (posted mode) for this ptdev.
If intr_src->pi_vcpu is 0, fall back to use the remapped mode.
@@ -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);
+
+ ir_table = (union dmar_ir_entry *)hpa2hva(dmar_unit->ir_table_addr);
+ ir_entry = ir_table + index;
+
+ 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.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;
+ *ir_entry = *irte;
+ }
iommu_flush_cache(ir_entry, sizeof(union dmar_ir_entry));
dmar_invalid_iec(dmar_unit, index, 0U, false);
}
