hv/mod_irq: decouple irq number reservation from ioapic
This is done be adding irq_rsvd_bitmap as an auxiliary bitmap besides irq_alloc_bitmap. Tracked-On: #5825 Signed-off-by: Peter Fang <peter.fang@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
parent
038e0cae92
commit
c46e3c71ac
|
@ -442,7 +442,7 @@ void ioapic_setup_irqs(void)
|
|||
gsi_table_data[gsi].ioapic_info.index = ioapic_id;
|
||||
|
||||
/* pinned irq before use it */
|
||||
if (alloc_irq_num(gsi) == IRQ_INVALID) {
|
||||
if (reserve_irq_num(gsi) == IRQ_INVALID) {
|
||||
pr_err("failed to alloc IRQ[%d]", gsi);
|
||||
gsi++;
|
||||
continue;
|
||||
|
|
|
@ -24,6 +24,7 @@ static spinlock_t irq_alloc_spinlock = { .head = 0U, .tail = 0U, };
|
|||
uint64_t irq_alloc_bitmap[IRQ_ALLOC_BITMAP_SIZE];
|
||||
struct irq_desc irq_desc_array[NR_IRQS];
|
||||
static struct x86_irq_data irq_data[NR_IRQS];
|
||||
static uint64_t irq_rsvd_bitmap[IRQ_ALLOC_BITMAP_SIZE];
|
||||
|
||||
static uint32_t vector_to_irq[NR_MAX_VECTOR + 1];
|
||||
|
||||
|
@ -45,7 +46,7 @@ static struct {
|
|||
* alloc an free irq if req_irq is IRQ_INVALID, or else set assigned
|
||||
* return: irq num on success, IRQ_INVALID on failure
|
||||
*/
|
||||
uint32_t alloc_irq_num(uint32_t req_irq)
|
||||
static uint32_t alloc_irq_num(uint32_t req_irq, bool reserve)
|
||||
{
|
||||
uint32_t irq = req_irq;
|
||||
uint64_t rflags;
|
||||
|
@ -66,6 +67,10 @@ uint32_t alloc_irq_num(uint32_t req_irq)
|
|||
} else {
|
||||
bitmap_set_nolock((uint16_t)(irq & 0x3FU),
|
||||
irq_alloc_bitmap + (irq >> 6U));
|
||||
if (reserve) {
|
||||
bitmap_set_nolock((uint16_t)(irq & 0x3FU),
|
||||
irq_rsvd_bitmap + (irq >> 6U));
|
||||
}
|
||||
}
|
||||
spinlock_irqrestore_release(&irq_alloc_spinlock, rflags);
|
||||
ret = irq;
|
||||
|
@ -73,6 +78,11 @@ uint32_t alloc_irq_num(uint32_t req_irq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
uint32_t reserve_irq_num(uint32_t irq)
|
||||
{
|
||||
return alloc_irq_num(irq, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* @pre: irq is not in irq_static_mappings
|
||||
* free irq num allocated via alloc_irq_num()
|
||||
|
@ -82,12 +92,14 @@ static void free_irq_num(uint32_t irq)
|
|||
uint64_t rflags;
|
||||
|
||||
if (irq < NR_IRQS) {
|
||||
if (!is_ioapic_irq(irq)) {
|
||||
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
|
||||
(void)bitmap_test_and_clear_nolock((uint16_t)(irq & 0x3FU),
|
||||
irq_alloc_bitmap + (irq >> 6U));
|
||||
spinlock_irqrestore_release(&irq_alloc_spinlock, rflags);
|
||||
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
|
||||
|
||||
if (bitmap_test((uint16_t)(irq & 0x3FU),
|
||||
irq_rsvd_bitmap + (irq >> 6U)) == false) {
|
||||
bitmap_clear_nolock((uint16_t)(irq & 0x3FU),
|
||||
irq_alloc_bitmap + (irq >> 6U));
|
||||
}
|
||||
spinlock_irqrestore_release(&irq_alloc_spinlock, rflags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,7 +210,7 @@ int32_t request_irq(uint32_t req_irq, irq_action_t action_fn, void *priv_data,
|
|||
uint64_t rflags;
|
||||
int32_t ret;
|
||||
|
||||
irq = alloc_irq_num(req_irq);
|
||||
irq = alloc_irq_num(req_irq, false);
|
||||
if (irq == IRQ_INVALID) {
|
||||
pr_err("[%s] invalid irq num", __func__);
|
||||
ret = -EINVAL;
|
||||
|
@ -432,11 +444,6 @@ void handle_nmi(__unused struct intr_excp_ctx *ctx)
|
|||
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32);
|
||||
}
|
||||
|
||||
static void prealloc_irq_num(uint32_t irq)
|
||||
{
|
||||
bitmap_set_nolock((uint16_t)(irq & 0x3FU), irq_alloc_bitmap + (irq >> 6U));
|
||||
}
|
||||
|
||||
static void init_irq_data_arch(struct irq_desc descs[])
|
||||
{
|
||||
uint32_t i;
|
||||
|
@ -471,7 +478,8 @@ static void init_irq_data_arch(struct irq_desc descs[])
|
|||
|
||||
irq_data[irq].vector = vr;
|
||||
vector_to_irq[vr] = irq;
|
||||
prealloc_irq_num(irq);
|
||||
|
||||
reserve_irq_num(irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ void setup_pi_notification(void);
|
|||
typedef void (*spurious_handler_t)(uint32_t vector);
|
||||
extern spurious_handler_t spurious_handler;
|
||||
|
||||
uint32_t alloc_irq_num(uint32_t req_irq);
|
||||
uint32_t alloc_irq_vector(uint32_t irq);
|
||||
|
||||
/* RFLAGS */
|
||||
|
@ -284,6 +283,19 @@ struct irq_desc {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reserve an interrupt num
|
||||
*
|
||||
* Reserved interrupt num will not be available for dynamic IRQ allocations.
|
||||
* This is normally used by the hypervisor for static IRQ mappings and/or
|
||||
* arch specific, e.g. IOAPIC, interrupts during initialization.
|
||||
*
|
||||
* @param[in] req_irq irq_num to be reserved
|
||||
*
|
||||
* @retval >=0 on success, IRQ_INVALID on failure
|
||||
*/
|
||||
uint32_t reserve_irq_num(uint32_t req_irq);
|
||||
|
||||
/**
|
||||
* @brief Request an interrupt
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue