diff --git a/hypervisor/arch/x86/irq.c b/hypervisor/arch/x86/irq.c index 61e32e943..841b25c23 100644 --- a/hypervisor/arch/x86/irq.c +++ b/hypervisor/arch/x86/irq.c @@ -10,6 +10,8 @@ static spinlock_t exception_spinlock = { .head = 0U, .tail = 0U, }; static spinlock_t irq_alloc_spinlock = { .head = 0U, .tail = 0U, }; +#define IRQ_ALLOC_BITMAP_SIZE INT_DIV_ROUNDUP(NR_IRQS, sizeof(uint64_t)) +static uint64_t irq_alloc_bitmap[IRQ_ALLOC_BITMAP_SIZE]; static struct irq_desc irq_desc_array[NR_IRQS]; static uint32_t vector_to_irq[NR_MAX_VECTOR + 1]; @@ -27,10 +29,8 @@ static uint32_t irq_static_mappings[NR_STATIC_MAPPINGS][2] = { */ uint32_t alloc_irq_num(uint32_t req_irq) { - uint32_t i; uint32_t irq = req_irq; uint64_t rflags; - struct irq_desc *desc; if ((irq >= NR_IRQS) && (irq != IRQ_INVALID)) { pr_err("[%s] invalid req_irq %u", __func__, req_irq); @@ -40,18 +40,12 @@ uint32_t alloc_irq_num(uint32_t req_irq) spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags); if (irq == IRQ_INVALID) { /* if no valid irq num given, find a free one */ - for (i = irq_gsi_num(); i < NR_IRQS; i++) { - desc = &irq_desc_array[i]; - if (desc->used == IRQ_NOT_ASSIGNED) { - irq = i; - break; - } - } + irq = ffz64_ex(irq_alloc_bitmap, NR_IRQS); + irq = (irq == NR_IRQS) ? IRQ_INVALID : irq; } if (irq != IRQ_INVALID) { - desc = &irq_desc_array[irq]; - desc->used = IRQ_ASSIGNED; + bitmap_set_nolock(irq & 0x3FU, irq_alloc_bitmap + (irq >> 6U)); } spinlock_irqrestore_release(&irq_alloc_spinlock, rflags); return irq; @@ -73,7 +67,8 @@ void free_irq_num(uint32_t irq) if ((irq_is_gsi(irq) == false) && (desc->vector <= VECTOR_DYNAMIC_END)) { spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags); - desc->used = IRQ_NOT_ASSIGNED; + bitmap_test_and_clear_nolock(irq & 0x3FU, + irq_alloc_bitmap + (irq >> 6U)); spinlock_irqrestore_release(&irq_alloc_spinlock, rflags); } } @@ -338,7 +333,7 @@ void dispatch_interrupt(struct intr_excp_ctx *ctx) goto ERR; } - if (desc->used == IRQ_NOT_ASSIGNED) { + if (bitmap_test(irq & 0x3FU, irq_alloc_bitmap + (irq >> 6U)) == 0U) { /* mask irq if possible */ goto ERR; } @@ -396,7 +391,6 @@ void get_cpu_interrupt_info(char *str_arg, int str_max) uint16_t pcpu_id; uint32_t irq, vector; int len, size = str_max; - struct irq_desc *desc; len = snprintf(str, size, "\r\nIRQ\tVECTOR"); size -= len; @@ -408,10 +402,9 @@ void get_cpu_interrupt_info(char *str_arg, int str_max) } for (irq = 0U; irq < NR_IRQS; irq++) { - desc = &irq_desc_array[irq]; vector = irq_to_vector(irq); - if ((desc->used != IRQ_NOT_ASSIGNED) && - (vector != VECTOR_INVALID)) { + if (bitmap_test(irq & 0x3FU, irq_alloc_bitmap + (irq >> 6U)) + && (vector != VECTOR_INVALID)) { len = snprintf(str, size, "\r\n%d\t0x%X", irq, vector); size -= len; str += len; @@ -447,8 +440,8 @@ static void init_irq_descs(void) uint32_t vr = irq_static_mappings[i][1]; irq_desc_array[irq].vector = vr; - irq_desc_array[irq].used = IRQ_ASSIGNED; vector_to_irq[vr] = irq; + bitmap_set_nolock(irq & 0x3FU, irq_alloc_bitmap + (irq >> 6U)); } } diff --git a/hypervisor/include/arch/x86/irq.h b/hypervisor/include/arch/x86/irq.h index bc2a3cb6b..7ba505ffe 100644 --- a/hypervisor/include/arch/x86/irq.h +++ b/hypervisor/include/arch/x86/irq.h @@ -24,7 +24,7 @@ #define NR_MAX_VECTOR 0xFFU #define VECTOR_INVALID (NR_MAX_VECTOR + 1U) -#define NR_IRQS (256U + 16U) +#define NR_IRQS 256U #define IRQ_INVALID 0xffffffffU #define TIMER_IRQ (NR_IRQS - 1U) diff --git a/hypervisor/include/common/irq.h b/hypervisor/include/common/irq.h index 442c1d286..0bf1c1eec 100644 --- a/hypervisor/include/common/irq.h +++ b/hypervisor/include/common/irq.h @@ -17,17 +17,11 @@ enum irq_mode { IRQ_DEASSERT, }; -enum irq_use_state { - IRQ_NOT_ASSIGNED = 0, - IRQ_ASSIGNED, -}; - typedef int (*irq_action_t)(uint32_t irq, void *priv_data); /* any field change in below required irq_lock protection with irqsave */ struct irq_desc { uint32_t irq; /* index to irq_desc_base */ - enum irq_use_state used; /* this irq have assigned to device */ uint32_t vector; /* assigned vector */ irq_action_t action; /* callback registered from component */