mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-05 11:36:50 +00:00
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:
parent
a7e53dd32f
commit
f3cae9e258
@ -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,7 +276,7 @@ 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;
|
||||
}
|
||||
@ -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));
|
||||
|
@ -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 &
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user