mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-06 12:06:25 +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];
|
uint64_t irq_alloc_bitmap[IRQ_ALLOC_BITMAP_SIZE];
|
||||||
struct irq_desc irq_desc_array[NR_IRQS];
|
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];
|
static uint32_t vector_to_irq[NR_MAX_VECTOR + 1];
|
||||||
|
|
||||||
spurious_handler_t spurious_handler;
|
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 alloc_irq_vector(uint32_t irq)
|
||||||
{
|
{
|
||||||
uint32_t vr;
|
uint32_t vr;
|
||||||
struct irq_desc *desc;
|
struct x86_irq_data *irqd;
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
|
|
||||||
if (irq < NR_IRQS) {
|
if (irq < NR_IRQS) {
|
||||||
desc = &irq_desc_array[irq];
|
irqd = &irq_data[irq];
|
||||||
|
|
||||||
if (desc->vector != VECTOR_INVALID) {
|
if (irqd->vector != VECTOR_INVALID) {
|
||||||
if (vector_to_irq[desc->vector] == irq) {
|
if (vector_to_irq[irqd->vector] == irq) {
|
||||||
/* statically binded */
|
/* statically binded */
|
||||||
vr = desc->vector;
|
vr = irqd->vector;
|
||||||
} else {
|
} else {
|
||||||
pr_err("[%s] irq[%u]:vector[%u] mismatch",
|
pr_err("[%s] irq[%u]:vector[%u] mismatch",
|
||||||
__func__, irq, desc->vector);
|
__func__, irq, irqd->vector);
|
||||||
vr = VECTOR_INVALID;
|
vr = VECTOR_INVALID;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -125,7 +127,7 @@ uint32_t alloc_irq_vector(uint32_t irq)
|
|||||||
for (vr = VECTOR_DYNAMIC_START;
|
for (vr = VECTOR_DYNAMIC_START;
|
||||||
vr <= VECTOR_DYNAMIC_END; vr++) {
|
vr <= VECTOR_DYNAMIC_END; vr++) {
|
||||||
if (vector_to_irq[vr] == IRQ_INVALID) {
|
if (vector_to_irq[vr] == IRQ_INVALID) {
|
||||||
desc->vector = vr;
|
irqd->vector = vr;
|
||||||
vector_to_irq[vr] = irq;
|
vector_to_irq[vr] = irq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -145,19 +147,19 @@ uint32_t alloc_irq_vector(uint32_t irq)
|
|||||||
/* free the vector allocated via alloc_irq_vector() */
|
/* free the vector allocated via alloc_irq_vector() */
|
||||||
static void free_irq_vector(uint32_t irq)
|
static void free_irq_vector(uint32_t irq)
|
||||||
{
|
{
|
||||||
struct irq_desc *desc;
|
struct x86_irq_data *irqd;
|
||||||
uint32_t vr;
|
uint32_t vr;
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
|
|
||||||
if (irq < NR_IRQS) {
|
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 */
|
/* do nothing for LEGACY_IRQ and static allocated ones */
|
||||||
|
|
||||||
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
|
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
|
||||||
vr = desc->vector;
|
vr = irqd->vector;
|
||||||
desc->vector = VECTOR_INVALID;
|
irqd->vector = VECTOR_INVALID;
|
||||||
|
|
||||||
vr &= NR_MAX_VECTOR;
|
vr &= NR_MAX_VECTOR;
|
||||||
if (vector_to_irq[vr] == irq) {
|
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);
|
spinlock_irqrestore_release(&desc->lock, rflags);
|
||||||
|
|
||||||
ret = (int32_t)irq;
|
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 {
|
} else {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
pr_err("%s: request irq(%u) vr(%u) failed, already requested", __func__,
|
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;
|
uint32_t ret;
|
||||||
if (irq < NR_IRQS) {
|
if (irq < NR_IRQS) {
|
||||||
ret = irq_desc_array[irq].vector;
|
ret = irq_data[irq].vector;
|
||||||
} else {
|
} else {
|
||||||
ret = VECTOR_INVALID;
|
ret = VECTOR_INVALID;
|
||||||
}
|
}
|
||||||
@ -336,6 +338,7 @@ void dispatch_interrupt(const struct intr_excp_ctx *ctx)
|
|||||||
uint32_t vr = ctx->vector;
|
uint32_t vr = ctx->vector;
|
||||||
uint32_t irq = vector_to_irq[vr];
|
uint32_t irq = vector_to_irq[vr];
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
|
struct x86_irq_data *irqd;
|
||||||
|
|
||||||
/* The value from vector_to_irq[] must be:
|
/* The value from vector_to_irq[] must be:
|
||||||
* IRQ_INVALID, which means the vector is not allocated;
|
* 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) {
|
if (irq < NR_IRQS) {
|
||||||
desc = &irq_desc_array[irq];
|
desc = &irq_desc_array[irq];
|
||||||
|
irqd = desc->arch_data;
|
||||||
per_cpu(irq_count, get_pcpu_id())[irq]++;
|
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))) {
|
bitmap_test((uint16_t)(irq & 0x3FU), irq_alloc_bitmap + (irq >> 6U))) {
|
||||||
#ifdef PROFILING_ON
|
#ifdef PROFILING_ON
|
||||||
/* Saves ctx info into irq_desc */
|
/* Saves ctx info into irq_desc */
|
||||||
desc->ctx_rip = ctx->rip;
|
irqd->ctx_rip = ctx->rip;
|
||||||
desc->ctx_rflags = ctx->rflags;
|
irqd->ctx_rflags = ctx->rflags;
|
||||||
desc->ctx_cs = ctx->cs;
|
irqd->ctx_cs = ctx->cs;
|
||||||
#endif
|
#endif
|
||||||
handle_irq(desc);
|
handle_irq(desc);
|
||||||
}
|
}
|
||||||
@ -428,8 +432,9 @@ static void init_irq_descs(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0U; i < NR_IRQS; i++) {
|
for (i = 0U; i < NR_IRQS; i++) {
|
||||||
|
irq_data[i].vector = VECTOR_INVALID;
|
||||||
irq_desc_array[i].irq = i;
|
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);
|
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 irq = irq_static_mappings[i].irq;
|
||||||
uint32_t vr = irq_static_mappings[i].vector;
|
uint32_t vr = irq_static_mappings[i].vector;
|
||||||
|
|
||||||
irq_desc_array[irq].vector = vr;
|
irq_data[irq].vector = vr;
|
||||||
vector_to_irq[vr] = irq;
|
vector_to_irq[vr] = irq;
|
||||||
bitmap_set_nolock((uint16_t)(irq & 0x3FU),
|
bitmap_set_nolock((uint16_t)(irq & 0x3FU),
|
||||||
irq_alloc_bitmap + (irq >> 6U));
|
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;
|
get_cpu_var(profiling_info.vm_info).external_vector = -1;
|
||||||
/* Attribute PMI to hypervisor context */
|
/* Attribute PMI to hypervisor context */
|
||||||
} else {
|
} else {
|
||||||
|
const struct x86_irq_data *irqd = irq_desc_array[irq].arch_data;
|
||||||
psample->csample.os_id = 0xFFFFU;
|
psample->csample.os_id = 0xFFFFU;
|
||||||
(void)memcpy_s(psample->csample.task, 16, "VMM\0", 4);
|
(void)memcpy_s(psample->csample.task, 16, "VMM\0", 4);
|
||||||
psample->csample.cpu_id = get_pcpu_id();
|
psample->csample.cpu_id = get_pcpu_id();
|
||||||
psample->csample.process_id = 0U;
|
psample->csample.process_id = 0U;
|
||||||
psample->csample.task_id = 0U;
|
psample->csample.task_id = 0U;
|
||||||
psample->csample.overflow_status = perf_ovf_status;
|
psample->csample.overflow_status = perf_ovf_status;
|
||||||
psample->csample.rip = irq_desc_array[irq].ctx_rip;
|
psample->csample.rip = irqd->ctx_rip;
|
||||||
psample->csample.rflags
|
psample->csample.rflags = (uint32_t)irqd->ctx_rflags;
|
||||||
= (uint32_t)irq_desc_array[irq].ctx_rflags;
|
psample->csample.cs = (uint32_t)irqd->ctx_cs;
|
||||||
psample->csample.cs = (uint32_t)irq_desc_array[irq].ctx_cs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sep_collection_switch &
|
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);
|
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
|
* @brief Interrupt descriptor
|
||||||
*
|
*
|
||||||
@ -254,18 +266,14 @@ typedef void (*irq_action_t)(uint32_t irq, void *priv_data);
|
|||||||
*/
|
*/
|
||||||
struct irq_desc {
|
struct irq_desc {
|
||||||
uint32_t irq; /**< index to irq_desc_base */
|
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 */
|
irq_action_t action; /**< callback registered from component */
|
||||||
void *priv_data; /**< irq_action private data */
|
void *priv_data; /**< irq_action private data */
|
||||||
uint32_t flags; /**< flags for trigger mode/ptdev */
|
uint32_t flags; /**< flags for trigger mode/ptdev */
|
||||||
|
|
||||||
spinlock_t lock;
|
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