mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 20:22:46 +00:00
hv: align the MAX_IR_ENTRIES to MAX_PT_IRQ_ENTRIES
The CONFIG_MAX_IR_ENTRIES and CONFIG_MAX_PT_IRQ_ENTRIES are separate configuration items, and they can be configured through configuration tool When the number of PT irq entries are more than IR entries, then some passthrough devices' irqs may failed to be protected by interrupt remapping or automatically injected by post-interrupt mechanism. And it waste memory if the CONFIG_MAX_IR_ENTRIES is larger. This patch replace the CONFIG_MAX_IR_ENTRIES to MAX_IR_ENTRIES and enforce it align to CONFIG_PT_IRQ_ENTRIES and round up to > 2^n as the IRTA_REG spec.This way can enforce all PT irqs works with IR or PI mechanism. Tracked-On: #6745 Signed-off-by: Chenli Wei <chenli.wei@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
58e27983b4
commit
022df1fb2e
@ -128,8 +128,8 @@ struct dmar_drhd_rt {
|
||||
|
||||
uint64_t root_table_addr;
|
||||
uint64_t ir_table_addr;
|
||||
uint64_t irte_alloc_bitmap[CONFIG_MAX_IR_ENTRIES / 64U];
|
||||
uint64_t irte_reserved_bitmap[CONFIG_MAX_IR_ENTRIES / 64U];
|
||||
uint64_t irte_alloc_bitmap[MAX_IR_ENTRIES / 64U];
|
||||
uint64_t irte_reserved_bitmap[MAX_IR_ENTRIES / 64U];
|
||||
uint64_t qi_queue;
|
||||
uint16_t qi_tail;
|
||||
|
||||
@ -152,7 +152,7 @@ struct context_table {
|
||||
};
|
||||
|
||||
struct intr_remap_table {
|
||||
struct page tables[CONFIG_MAX_IR_ENTRIES/DMAR_NUM_IR_ENTRIES_PER_PAGE];
|
||||
struct page tables[MAX_IR_ENTRIES/DMAR_NUM_IR_ENTRIES_PER_PAGE];
|
||||
};
|
||||
|
||||
static inline uint8_t *get_root_table(uint32_t dmar_index)
|
||||
@ -672,7 +672,7 @@ static void dmar_set_intr_remap_table(struct dmar_drhd_rt *dmar_unit)
|
||||
spinlock_obtain(&(dmar_unit->lock));
|
||||
|
||||
/* Set number of bits needed to represent the entries minus 1 */
|
||||
size = (uint8_t) fls32(CONFIG_MAX_IR_ENTRIES) - 1U;
|
||||
size = (uint8_t) fls32(MAX_IR_ENTRIES) - 1U;
|
||||
address = dmar_unit->ir_table_addr | DMAR_IR_ENABLE_EIM | size;
|
||||
|
||||
iommu_write64(dmar_unit, DMAR_IRTA_REG, address);
|
||||
@ -1276,7 +1276,7 @@ static uint16_t alloc_irtes(struct dmar_drhd_rt *dmar_unit, const uint16_t num)
|
||||
ASSERT((bitmap_weight(num) == 1U) && (num <= 32U));
|
||||
|
||||
spinlock_obtain(&dmar_unit->lock);
|
||||
for (irte_idx = 0U; irte_idx < CONFIG_MAX_IR_ENTRIES; irte_idx += num) {
|
||||
for (irte_idx = 0U; irte_idx < MAX_IR_ENTRIES; irte_idx += num) {
|
||||
test_mask = mask << (irte_idx & 0x3FU);
|
||||
if ((dmar_unit->irte_alloc_bitmap[irte_idx >> 6U] & test_mask) == 0UL) {
|
||||
dmar_unit->irte_alloc_bitmap[irte_idx >> 6U] |= test_mask;
|
||||
@ -1285,7 +1285,7 @@ static uint16_t alloc_irtes(struct dmar_drhd_rt *dmar_unit, const uint16_t num)
|
||||
}
|
||||
spinlock_release(&dmar_unit->lock);
|
||||
|
||||
return (irte_idx < CONFIG_MAX_IR_ENTRIES) ? irte_idx: INVALID_IRTE_ID;
|
||||
return (irte_idx < MAX_IR_ENTRIES) ? irte_idx: INVALID_IRTE_ID;
|
||||
}
|
||||
|
||||
static bool is_irte_reserved(const struct dmar_drhd_rt *dmar_unit, uint16_t index)
|
||||
@ -1309,7 +1309,7 @@ int32_t dmar_reserve_irte(const struct intr_source *intr_src, uint16_t num, uint
|
||||
|
||||
if (is_dmar_unit_valid(dmar_unit, sid)) {
|
||||
*start_id = alloc_irtes(dmar_unit, num);
|
||||
if (*start_id < CONFIG_MAX_IR_ENTRIES) {
|
||||
if (*start_id < MAX_IR_ENTRIES) {
|
||||
dmar_unit->irte_reserved_bitmap[*start_id >> 6U] |= mask << (*start_id & 0x3FU);
|
||||
}
|
||||
ret = 0;
|
||||
@ -1346,7 +1346,7 @@ int32_t dmar_assign_irte(const struct intr_source *intr_src, union dmar_ir_entry
|
||||
if (idx_in == INVALID_IRTE_ID) {
|
||||
*idx_out = alloc_irtes(dmar_unit, 1U);
|
||||
}
|
||||
if (*idx_out < CONFIG_MAX_IR_ENTRIES) {
|
||||
if (*idx_out < MAX_IR_ENTRIES) {
|
||||
ir_entry = ir_table + *idx_out;
|
||||
|
||||
if (intr_src->pid_paddr != 0UL) {
|
||||
@ -1397,7 +1397,7 @@ void dmar_free_irte(const struct intr_source *intr_src, uint16_t index)
|
||||
dmar_unit = ioapic_to_dmaru(intr_src->src.ioapic_id, &sid);
|
||||
}
|
||||
|
||||
if (is_dmar_unit_valid(dmar_unit, sid) && (index < CONFIG_MAX_IR_ENTRIES)) {
|
||||
if (is_dmar_unit_valid(dmar_unit, sid) && (index < MAX_IR_ENTRIES)) {
|
||||
ir_table = (union dmar_ir_entry *)hpa2hva(dmar_unit->ir_table_addr);
|
||||
ir_entry = ir_table + index;
|
||||
ir_entry->bits.remap.present = 0x0UL;
|
||||
|
@ -42,6 +42,13 @@
|
||||
#define DMAR_ICS_REG 0x9cU /* Invalidation complete status register */
|
||||
#define DMAR_IRTA_REG 0xb8U /* Interrupt remapping table addr register */
|
||||
|
||||
/* Make sure all PT IRQs work w/ interrupt remapping or post interrupt */
|
||||
#if (CONFIG_MAX_PT_IRQ_ENTRIES <= 256)
|
||||
#define MAX_IR_ENTRIES 256
|
||||
#else
|
||||
#define MAX_IR_ENTRIES powerof2_roundup(CONFIG_MAX_PT_IRQ_ENTRIES)
|
||||
#endif
|
||||
|
||||
/* Values for entry_type in ACPI_DMAR_DEVICE_SCOPE - device types */
|
||||
enum acpi_dmar_scope_type {
|
||||
ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
|
||||
|
@ -25,6 +25,27 @@
|
||||
/** Replaces 'x' by the string "x". */
|
||||
#define STRINGIFY(x) #x
|
||||
|
||||
/*
|
||||
* This algorithm get the round up 2^n
|
||||
*
|
||||
* n = input - 1; 0x1002 ----> 0x1001
|
||||
* n |= n >> 1; 0x1001 | 0x800
|
||||
* n |= n >> 2; 0x1801 | 0x600
|
||||
* n |= n >> 4; 0x1e01 | 0x1e0
|
||||
* n |= n >> 8; 0x1fe1 | 0x1f
|
||||
* n |= n >> 16; 0x1fff
|
||||
* n |= n >> 32; 0x1fff
|
||||
* n += 1; 0x2000
|
||||
*/
|
||||
#define ROUND0(x) ((x)-1)
|
||||
#define ROUND1(x) (ROUND0(x) |(ROUND0(x)>>1))
|
||||
#define ROUND2(x) (ROUND1(x) |(ROUND1(x)>>2))
|
||||
#define ROUND4(x) (ROUND2(x) |(ROUND2(x)>>4))
|
||||
#define ROUND8(x) (ROUND4(x) |(ROUND4(x)>>8))
|
||||
#define ROUND16(x) (ROUND8(x) |(ROUND8(x)>>16))
|
||||
#define ROUND32(x) (ROUND16(x) |(ROUND16(x)>>32))
|
||||
#define powerof2_roundup(x) ((ROUND32(x) == (~0UL)) ? ~0UL : (ROUND32(x) +1))
|
||||
|
||||
/* Macro used to check if a value is aligned to the required boundary.
|
||||
* Returns TRUE if aligned; FALSE if not aligned
|
||||
* NOTE: The required alignment must be a power of 2 (2, 4, 8, 16, 32, etc)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <asm/guest/vcpu.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/guest/trusty.h>
|
||||
#include <asm/vtd.h>
|
||||
|
||||
#define CAT__(A,B) A ## B
|
||||
#define CAT_(A,B) CAT__(A,B)
|
||||
@ -28,8 +29,8 @@ typedef int32_t CAT_(CTA_DummyType,__LINE__)[(expr) ? 1 : -1]
|
||||
#error "CONFIG_HV_RAM_SIZE must be integral multiple of 2MB"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_MAX_IR_ENTRIES < 256U) || (CONFIG_MAX_IR_ENTRIES & (CONFIG_MAX_IR_ENTRIES -1)) != 0U)
|
||||
#error "CONFIG_MAX_IR_ENTRIES must >=256 and be 2^n"
|
||||
#if ((MAX_IR_ENTRIES < 256U) || (MAX_IR_ENTRIES > 0x10000U) || (MAX_IR_ENTRIES & (MAX_IR_ENTRIES -1)) != 0U)
|
||||
#error "MAX_IR_ENTRIES must in the region of [256,0x10000] and be 2^n"
|
||||
#endif
|
||||
|
||||
/* Build time sanity checks to make sure hard-coded offset
|
||||
|
Loading…
Reference in New Issue
Block a user