hv: vtd: add an API to reserve continuous irtes

dmar_reserve_irte is added to reserve N coutinuous IRTEs.
N could be 1, 2, 4, 8, 16, or 32.

The reserved IRTEs will not be freed.

Tracked-On:#4831
Signed-off-by: Binbin Wu <binbin.wu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Binbin Wu 2020-05-29 23:35:36 +08:00 committed by wenlingz
parent 7bfcc673a6
commit da1788c9a3
2 changed files with 42 additions and 0 deletions

View File

@ -1290,6 +1290,33 @@ static bool is_irte_reserved(const struct dmar_drhd_rt *dmar_unit, uint16_t inde
return ((dmar_unit->irte_reserved_bitmap[index >> 6U] & (1UL << (index & 0x3FU))) != 0UL);
}
int32_t dmar_reserve_irte(const struct intr_source *intr_src, uint16_t num, uint16_t *start_id)
{
struct dmar_drhd_rt *dmar_unit;
union pci_bdf sid;
uint64_t mask = (1UL << num) - 1U;
int32_t ret = -EINVAL;
if (intr_src->is_msi) {
dmar_unit = device_to_dmaru((uint8_t)intr_src->src.msi.bits.b, intr_src->src.msi.fields.devfun);
sid.value = (uint16_t)(intr_src->src.msi.value);
} else {
dmar_unit = ioapic_to_dmaru(intr_src->src.ioapic_id, &sid);
}
if (is_dmar_unit_valid(dmar_unit, sid)) {
*start_id = alloc_irtes(dmar_unit, num);
if (*start_id < CONFIG_MAX_IR_ENTRIES) {
dmar_unit->irte_reserved_bitmap[*start_id >> 6U] |= mask << (*start_id & 0x3FU);
}
ret = 0;
}
pr_dbg("%s: for dev 0x%x:%x.%x, reserve %u entry for MSI(%d), start from %d",
__func__, sid.bits.b, sid.bits.d, sid.bits.f, num, intr_src->is_msi, *start_id);
return ret;
}
int32_t dmar_assign_irte(const struct intr_source *intr_src, union dmar_ir_entry *irte,
uint16_t idx_in, uint16_t *idx_out)
{

View File

@ -671,6 +671,21 @@ void resume_iommu(void);
*/
int32_t init_iommu(void);
/**
* @brief Reserve num continuous IRTEs.
*
* @param[in] intr_src filled with type of interrupt source and the source
* @param[in] num number of IRTEs to reserve
* @param[out] start_id stard index of reserved IRTEs, caller should check the value is INVALID_IRTE_ID or not.
*
* @retval 0 on success, caller should check whether the returned start index is valid or not.
* @retval -EINVAL if corresponding DMAR is not preset.
*
* @pre num can only be 2, 4, 8, 16 or 32
*
*/
int32_t dmar_reserve_irte(const struct intr_source *intr_src, uint16_t num, uint16_t *start_id);
/**
* @brief Assign RTE for Interrupt Remapping Table.
*