hv/mod_irq: hide arch specific data in irq_desc

Arch specific IRQ data is now an opaque pointer in irq_desc.

This is a preparation step for spliting IRQ handling into common
and architecture specific parts.

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:
Liang Yi 2021-03-12 21:13:20 +08:00 committed by wenlingz
parent a7e53dd32f
commit f3cae9e258
3 changed files with 44 additions and 31 deletions

View File

@ -23,6 +23,8 @@ 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 uint32_t vector_to_irq[NR_MAX_VECTOR + 1];
spurious_handler_t spurious_handler;
@ -100,20 +102,20 @@ static void free_irq_num(uint32_t irq)
uint32_t alloc_irq_vector(uint32_t irq)
{
uint32_t vr;
struct irq_desc *desc;
struct x86_irq_data *irqd;
uint64_t rflags;
uint32_t ret;
if (irq < NR_IRQS) {
desc = &irq_desc_array[irq];
irqd = &irq_data[irq];
if (desc->vector != VECTOR_INVALID) {
if (vector_to_irq[desc->vector] == irq) {
if (irqd->vector != VECTOR_INVALID) {
if (vector_to_irq[irqd->vector] == irq) {
/* statically binded */
vr = desc->vector;
vr = irqd->vector;
} else {
pr_err("[%s] irq[%u]:vector[%u] mismatch",
__func__, irq, desc->vector);
__func__, irq, irqd->vector);
vr = VECTOR_INVALID;
}
} else {
@ -125,7 +127,7 @@ uint32_t alloc_irq_vector(uint32_t irq)
for (vr = VECTOR_DYNAMIC_START;
vr <= VECTOR_DYNAMIC_END; vr++) {
if (vector_to_irq[vr] == IRQ_INVALID) {
desc->vector = vr;
irqd->vector = vr;
vector_to_irq[vr] = irq;
break;
}
@ -145,19 +147,19 @@ uint32_t alloc_irq_vector(uint32_t irq)
/* free the vector allocated via alloc_irq_vector() */
static void free_irq_vector(uint32_t irq)
{
struct irq_desc *desc;
struct x86_irq_data *irqd;
uint32_t vr;
uint64_t rflags;
if (irq < NR_IRQS) {
desc = &irq_desc_array[irq];
irqd = &irq_data[irq];
if ((irq >= NR_LEGACY_IRQ) && (desc->vector < VECTOR_FIXED_START)) {
if ((irq >= NR_LEGACY_IRQ) && (irqd->vector < VECTOR_FIXED_START)) {
/* do nothing for LEGACY_IRQ and static allocated ones */
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
vr = desc->vector;
desc->vector = VECTOR_INVALID;
vr = irqd->vector;
irqd->vector = VECTOR_INVALID;
vr &= NR_MAX_VECTOR;
if (vector_to_irq[vr] == irq) {
@ -220,7 +222,7 @@ int32_t request_irq(uint32_t req_irq, irq_action_t action_fn, void *priv_data,
spinlock_irqrestore_release(&desc->lock, rflags);
ret = (int32_t)irq;
dev_dbg(DBG_LEVEL_IRQ, "[%s] irq%d vr:0x%x", __func__, irq, desc->vector);
dev_dbg(DBG_LEVEL_IRQ, "[%s] irq%d vr:0x%x", __func__, irq, vector);
} else {
ret = -EBUSY;
pr_err("%s: request irq(%u) vr(%u) failed, already requested", __func__,
@ -274,9 +276,9 @@ uint32_t irq_to_vector(uint32_t irq)
{
uint32_t ret;
if (irq < NR_IRQS) {
ret = irq_desc_array[irq].vector;
ret = irq_data[irq].vector;
} else {
ret = VECTOR_INVALID;
ret = VECTOR_INVALID;
}
return ret;
@ -336,6 +338,7 @@ void dispatch_interrupt(const struct intr_excp_ctx *ctx)
uint32_t vr = ctx->vector;
uint32_t irq = vector_to_irq[vr];
struct irq_desc *desc;
struct x86_irq_data *irqd;
/* The value from vector_to_irq[] must be:
* IRQ_INVALID, which means the vector is not allocated;
@ -345,15 +348,16 @@ void dispatch_interrupt(const struct intr_excp_ctx *ctx)
*/
if (irq < NR_IRQS) {
desc = &irq_desc_array[irq];
irqd = desc->arch_data;
per_cpu(irq_count, get_pcpu_id())[irq]++;
if ((vr == desc->vector) &&
if ((vr == irqd->vector) &&
bitmap_test((uint16_t)(irq & 0x3FU), irq_alloc_bitmap + (irq >> 6U))) {
#ifdef PROFILING_ON
/* Saves ctx info into irq_desc */
desc->ctx_rip = ctx->rip;
desc->ctx_rflags = ctx->rflags;
desc->ctx_cs = ctx->cs;
irqd->ctx_rip = ctx->rip;
irqd->ctx_rflags = ctx->rflags;
irqd->ctx_cs = ctx->cs;
#endif
handle_irq(desc);
}
@ -428,8 +432,9 @@ static void init_irq_descs(void)
}
for (i = 0U; i < NR_IRQS; i++) {
irq_data[i].vector = VECTOR_INVALID;
irq_desc_array[i].irq = i;
irq_desc_array[i].vector = VECTOR_INVALID;
irq_desc_array[i].arch_data = &irq_data[i];
spinlock_init(&irq_desc_array[i].lock);
}
@ -442,7 +447,7 @@ static void init_irq_descs(void)
uint32_t irq = irq_static_mappings[i].irq;
uint32_t vr = irq_static_mappings[i].vector;
irq_desc_array[irq].vector = vr;
irq_data[irq].vector = vr;
vector_to_irq[vr] = irq;
bitmap_set_nolock((uint16_t)(irq & 0x3FU),
irq_alloc_bitmap + (irq >> 6U));

View File

@ -637,16 +637,16 @@ static void profiling_pmi_handler(uint32_t irq, __unused void *data)
get_cpu_var(profiling_info.vm_info).external_vector = -1;
/* Attribute PMI to hypervisor context */
} else {
const struct x86_irq_data *irqd = irq_desc_array[irq].arch_data;
psample->csample.os_id = 0xFFFFU;
(void)memcpy_s(psample->csample.task, 16, "VMM\0", 4);
psample->csample.cpu_id = get_pcpu_id();
psample->csample.process_id = 0U;
psample->csample.task_id = 0U;
psample->csample.overflow_status = perf_ovf_status;
psample->csample.rip = irq_desc_array[irq].ctx_rip;
psample->csample.rflags
= (uint32_t)irq_desc_array[irq].ctx_rflags;
psample->csample.cs = (uint32_t)irq_desc_array[irq].ctx_cs;
psample->csample.rip = irqd->ctx_rip;
psample->csample.rflags = (uint32_t)irqd->ctx_rflags;
psample->csample.cs = (uint32_t)irqd->ctx_cs;
}
if ((sep_collection_switch &

View File

@ -247,6 +247,18 @@ extern uint64_t irq_alloc_bitmap[IRQ_ALLOC_BITMAP_SIZE];
typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
/*
* x86 irq data
*/
struct x86_irq_data {
uint32_t vector; /**< assigned vector */
#ifdef PROFILING_ON
uint64_t ctx_rip;
uint64_t ctx_rflags;
uint64_t ctx_cs;
#endif
};
/**
* @brief Interrupt descriptor
*
@ -254,18 +266,14 @@ typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
*/
struct irq_desc {
uint32_t irq; /**< index to irq_desc_base */
uint32_t vector; /**< assigned vector */
void *arch_data; /**< arch-specific data */
irq_action_t action; /**< callback registered from component */
void *priv_data; /**< irq_action private data */
uint32_t flags; /**< flags for trigger mode/ptdev */
spinlock_t lock;
#ifdef PROFILING_ON
uint64_t ctx_rip;
uint64_t ctx_rflags;
uint64_t ctx_cs;
#endif
};
/**