mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-01 17:52:26 +00:00
hv: pirq: remove unnecessary dev_handler_node struct
Since we don't support shared irq, dev_handler_node which works as action node, is not needed anymore. This commit removes the dev_handler_node struct and does some relevant changes, including: - moves necessary fields to struct irq_desc: action, priv_data, name; and removes unused handler_data; - changes return type of pri_/normal_register_handler() from dev_handler_node* to int32_t, which is irq num (>= 0) on success, and errno (> 0) on failure. - changes unregister_irq_handler() to take argument unint32_t instead of dev_handler_node*; - changes are made to the places where these APIs are called. Signed-off-by: Yan, Like <like.yan@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
d773df9135
commit
f6e45c9b13
@ -142,7 +142,7 @@ lookup_entry_by_vintx(struct vm *vm, uint8_t vpin,
|
|||||||
static void
|
static void
|
||||||
ptdev_update_irq_handler(struct vm *vm, struct ptdev_remapping_info *entry)
|
ptdev_update_irq_handler(struct vm *vm, struct ptdev_remapping_info *entry)
|
||||||
{
|
{
|
||||||
uint32_t phys_irq = dev_to_irq(entry->node);
|
uint32_t phys_irq = entry->allocated_pirq;
|
||||||
struct ptdev_intx_info *intx = &entry->ptdev_intr_info.intx;
|
struct ptdev_intx_info *intx = &entry->ptdev_intr_info.intx;
|
||||||
|
|
||||||
if (entry->type == PTDEV_INTR_MSI) {
|
if (entry->type == PTDEV_INTR_MSI) {
|
||||||
@ -235,8 +235,8 @@ ptdev_build_physical_rte(struct vm *vm,
|
|||||||
struct ptdev_remapping_info *entry)
|
struct ptdev_remapping_info *entry)
|
||||||
{
|
{
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
uint32_t phys_irq = dev_to_irq(entry->node);
|
uint32_t phys_irq = entry->allocated_pirq;
|
||||||
uint32_t vector = dev_to_vector(entry->node);
|
uint32_t vector = irq_to_vector(phys_irq);
|
||||||
struct ptdev_intx_info *intx = &entry->ptdev_intr_info.intx;
|
struct ptdev_intx_info *intx = &entry->ptdev_intr_info.intx;
|
||||||
|
|
||||||
if (intx->vpin_src == PTDEV_VPIN_IOAPIC) {
|
if (intx->vpin_src == PTDEV_VPIN_IOAPIC) {
|
||||||
@ -457,7 +457,7 @@ static void remove_intx_remapping(struct vm *vm, uint8_t virt_pin, bool pic_pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_entry_active(entry)) {
|
if (is_entry_active(entry)) {
|
||||||
phys_irq = dev_to_irq(entry->node);
|
phys_irq = entry->allocated_pirq;
|
||||||
if (!irq_is_gsi(phys_irq)) {
|
if (!irq_is_gsi(phys_irq)) {
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
@ -509,8 +509,8 @@ static void ptdev_intr_handle_irq(struct vm *vm,
|
|||||||
|
|
||||||
dev_dbg(ACRN_DBG_PTIRQ,
|
dev_dbg(ACRN_DBG_PTIRQ,
|
||||||
"dev-assign: irq=0x%x assert vr: 0x%x vRTE=0x%lx",
|
"dev-assign: irq=0x%x assert vr: 0x%x vRTE=0x%lx",
|
||||||
dev_to_irq(entry->node),
|
entry->allocated_pirq,
|
||||||
irq_to_vector(dev_to_irq(entry->node)),
|
irq_to_vector(entry->allocated_pirq),
|
||||||
rte.full);
|
rte.full);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -570,9 +570,9 @@ void ptdev_softirq(__unused uint16_t cpu_id)
|
|||||||
msi->vmsi_data);
|
msi->vmsi_data);
|
||||||
dev_dbg(ACRN_DBG_PTIRQ,
|
dev_dbg(ACRN_DBG_PTIRQ,
|
||||||
"dev-assign: irq=0x%x MSI VR: 0x%x-0x%x",
|
"dev-assign: irq=0x%x MSI VR: 0x%x-0x%x",
|
||||||
dev_to_irq(entry->node),
|
entry->allocated_pirq,
|
||||||
msi->virt_vector,
|
msi->virt_vector,
|
||||||
irq_to_vector(dev_to_irq(entry->node)));
|
irq_to_vector(entry->allocated_pirq));
|
||||||
dev_dbg(ACRN_DBG_PTIRQ,
|
dev_dbg(ACRN_DBG_PTIRQ,
|
||||||
" vmsi_addr: 0x%x vmsi_data: 0x%x",
|
" vmsi_addr: 0x%x vmsi_data: 0x%x",
|
||||||
msi->vmsi_addr,
|
msi->vmsi_addr,
|
||||||
@ -671,10 +671,11 @@ int ptdev_msix_remap(struct vm *vm, uint16_t virt_bdf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* build physical config MSI, update to info->pmsi_xxx */
|
/* build physical config MSI, update to info->pmsi_xxx */
|
||||||
ptdev_build_physical_msi(vm, info, dev_to_vector(entry->node));
|
ptdev_build_physical_msi(vm, info, irq_to_vector(entry->allocated_pirq));
|
||||||
entry->ptdev_intr_info.msi = *info;
|
entry->ptdev_intr_info.msi = *info;
|
||||||
entry->ptdev_intr_info.msi.virt_vector = info->vmsi_data & 0xFFU;
|
entry->ptdev_intr_info.msi.virt_vector = info->vmsi_data & 0xFFU;
|
||||||
entry->ptdev_intr_info.msi.phys_vector = dev_to_vector(entry->node);
|
entry->ptdev_intr_info.msi.phys_vector =
|
||||||
|
irq_to_vector(entry->allocated_pirq);
|
||||||
|
|
||||||
/* update irq handler according to info in guest */
|
/* update irq handler according to info in guest */
|
||||||
ptdev_update_irq_handler(vm, entry);
|
ptdev_update_irq_handler(vm, entry);
|
||||||
@ -709,7 +710,7 @@ static void activate_physical_ioapic(struct vm *vm,
|
|||||||
struct ptdev_remapping_info *entry)
|
struct ptdev_remapping_info *entry)
|
||||||
{
|
{
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
uint32_t phys_irq = dev_to_irq(entry->node);
|
uint32_t phys_irq = entry->allocated_pirq;
|
||||||
|
|
||||||
/* disable interrupt */
|
/* disable interrupt */
|
||||||
GSI_MASK_IRQ(phys_irq);
|
GSI_MASK_IRQ(phys_irq);
|
||||||
@ -999,8 +1000,8 @@ static void get_entry_info(struct ptdev_remapping_info *entry, char *type,
|
|||||||
*bdf = 0U;
|
*bdf = 0U;
|
||||||
*vbdf = 0U;
|
*vbdf = 0U;
|
||||||
}
|
}
|
||||||
*irq = dev_to_irq(entry->node);
|
*irq = entry->allocated_pirq;
|
||||||
*vector = dev_to_vector(entry->node);
|
*vector = irq_to_vector(entry->allocated_pirq);
|
||||||
} else {
|
} else {
|
||||||
(void)strcpy_s(type, 16U, "NONE");
|
(void)strcpy_s(type, 16U, "NONE");
|
||||||
*irq = IRQ_INVALID;
|
*irq = IRQ_INVALID;
|
||||||
|
@ -151,31 +151,12 @@ static void disable_pic_irq(void)
|
|||||||
pio_write8(0xffU, 0x21U);
|
pio_write8(0xffU, 0x21U);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int32_t common_register_handler(uint32_t irq_arg,
|
||||||
irq_desc_append_dev(struct irq_desc *desc, void *node)
|
|
||||||
{
|
|
||||||
spinlock_rflags;
|
|
||||||
|
|
||||||
spinlock_irqsave_obtain(&desc->irq_lock);
|
|
||||||
|
|
||||||
ASSERT(desc->action == NULL, "irq already registered");
|
|
||||||
/* assign if first node */
|
|
||||||
desc->action = node;
|
|
||||||
desc->used = IRQ_ASSIGNED;
|
|
||||||
if (desc->irq_handler == NULL) {
|
|
||||||
desc->irq_handler = common_handler_edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_irqrestore_release(&desc->irq_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dev_handler_node*
|
|
||||||
common_register_handler(uint32_t irq_arg,
|
|
||||||
struct irq_request_info *info)
|
struct irq_request_info *info)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *node = NULL;
|
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
uint32_t irq = irq_arg;
|
uint32_t irq = irq_arg;
|
||||||
|
spinlock_rflags;
|
||||||
|
|
||||||
/* ======================================================
|
/* ======================================================
|
||||||
* This is low level ISR handler registering function
|
* This is low level ISR handler registering function
|
||||||
@ -217,43 +198,48 @@ common_register_handler(uint32_t irq_arg,
|
|||||||
|
|
||||||
if (irq >= NR_IRQS) {
|
if (irq >= NR_IRQS) {
|
||||||
pr_err("failed to assign IRQ");
|
pr_err("failed to assign IRQ");
|
||||||
goto OUT;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
node = calloc(1U, sizeof(struct dev_handler_node));
|
|
||||||
if (node == NULL) {
|
|
||||||
pr_err("failed to alloc node");
|
|
||||||
irq_desc_try_free_vector(irq);
|
|
||||||
goto OUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = &irq_desc_array[irq];
|
desc = &irq_desc_array[irq];
|
||||||
irq_desc_append_dev(desc, node);
|
if (desc->irq_handler == NULL) {
|
||||||
|
desc->irq_handler = common_handler_edge;
|
||||||
|
}
|
||||||
|
|
||||||
if (info->vector >= VECTOR_FIXED_START &&
|
if (info->vector >= VECTOR_FIXED_START &&
|
||||||
info->vector <= VECTOR_FIXED_END) {
|
info->vector <= VECTOR_FIXED_END) {
|
||||||
irq_desc_set_vector(irq, info->vector);
|
irq_desc_set_vector(irq, info->vector);
|
||||||
} else if (info->vector > NR_MAX_VECTOR) {
|
} else if (info->vector > NR_MAX_VECTOR) {
|
||||||
irq_desc_alloc_vector(irq);
|
irq_desc_alloc_vector(irq);
|
||||||
} else {
|
|
||||||
pr_err("the input vector is not correct");
|
|
||||||
free(node);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node->dev_handler = info->func;
|
if (desc->vector == VECTOR_INVALID) {
|
||||||
node->dev_data = info->dev_data;
|
pr_err("the input vector is not correct");
|
||||||
node->desc = desc;
|
/* FIXME: free allocated irq */
|
||||||
/* we are okay using strcpy_s here even with spinlock
|
return -EINVAL;
|
||||||
* since no #PG in HV right now
|
}
|
||||||
*/
|
|
||||||
(void)strcpy_s(node->name, 32U, info->name);
|
if (desc->action == NULL) {
|
||||||
|
spinlock_irqsave_obtain(&desc->irq_lock);
|
||||||
|
desc->priv_data = info->priv_data;
|
||||||
|
desc->action = info->func;
|
||||||
|
|
||||||
|
/* we are okay using strcpy_s here even with spinlock
|
||||||
|
* since no #PG in HV right now
|
||||||
|
*/
|
||||||
|
(void)strcpy_s(desc->name, 32U, info->name);
|
||||||
|
|
||||||
|
spinlock_irqrestore_release(&desc->irq_lock);
|
||||||
|
} else {
|
||||||
|
pr_err("%s: request irq(%u) vr(%u) for %s failed,\
|
||||||
|
already requested", __func__,
|
||||||
|
irq, irq_to_vector(irq), info->name);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_IRQ, "[%s] %s irq%d vr:0x%x",
|
dev_dbg(ACRN_DBG_IRQ, "[%s] %s irq%d vr:0x%x",
|
||||||
__func__, node->name, irq, desc->vector);
|
__func__, info->name, irq, desc->vector);
|
||||||
|
return (int32_t)irq;
|
||||||
OUT:
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* it is safe to call irq_desc_alloc_vector multiple times*/
|
/* it is safe to call irq_desc_alloc_vector multiple times*/
|
||||||
@ -318,16 +304,6 @@ uint32_t irq_to_vector(uint32_t irq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dev_to_irq(struct dev_handler_node *node)
|
|
||||||
{
|
|
||||||
return node->desc->irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t dev_to_vector(struct dev_handler_node *node)
|
|
||||||
{
|
|
||||||
return node->desc->vector;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_default_irqs(uint16_t cpu_id)
|
void init_default_irqs(uint16_t cpu_id)
|
||||||
{
|
{
|
||||||
if (cpu_id != BOOT_CPU_ID) {
|
if (cpu_id != BOOT_CPU_ID) {
|
||||||
@ -395,7 +371,7 @@ void dispatch_interrupt(struct intr_excp_ctx *ctx)
|
|||||||
goto ERR;
|
goto ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->irq_handler(desc, desc->handler_data);
|
desc->irq_handler(desc, NULL);
|
||||||
return;
|
return;
|
||||||
ERR:
|
ERR:
|
||||||
handle_spurious_interrupt(vr);
|
handle_spurious_interrupt(vr);
|
||||||
@ -427,7 +403,7 @@ void partition_mode_dispatch_interrupt(struct intr_excp_ctx *ctx)
|
|||||||
int handle_level_interrupt_common(struct irq_desc *desc,
|
int handle_level_interrupt_common(struct irq_desc *desc,
|
||||||
__unused void *handler_data)
|
__unused void *handler_data)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *action = desc->action;
|
irq_action_t action = desc->action;
|
||||||
spinlock_rflags;
|
spinlock_rflags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -451,9 +427,9 @@ int handle_level_interrupt_common(struct irq_desc *desc,
|
|||||||
/* Send EOI to LAPIC/IOAPIC IRR */
|
/* Send EOI to LAPIC/IOAPIC IRR */
|
||||||
send_lapic_eoi();
|
send_lapic_eoi();
|
||||||
|
|
||||||
if (action != NULL && action->dev_handler != NULL) {
|
if (action != NULL) {
|
||||||
action->dev_handler(desc->irq, action->dev_data);
|
action(desc->irq, desc->priv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq_is_gsi(desc->irq)) {
|
if (irq_is_gsi(desc->irq)) {
|
||||||
GSI_UNMASK_IRQ(desc->irq);
|
GSI_UNMASK_IRQ(desc->irq);
|
||||||
@ -467,7 +443,7 @@ int handle_level_interrupt_common(struct irq_desc *desc,
|
|||||||
|
|
||||||
int common_handler_edge(struct irq_desc *desc, __unused void *handler_data)
|
int common_handler_edge(struct irq_desc *desc, __unused void *handler_data)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *action = desc->action;
|
irq_action_t action = desc->action;
|
||||||
spinlock_rflags;
|
spinlock_rflags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -486,8 +462,8 @@ int common_handler_edge(struct irq_desc *desc, __unused void *handler_data)
|
|||||||
/* Send EOI to LAPIC/IOAPIC IRR */
|
/* Send EOI to LAPIC/IOAPIC IRR */
|
||||||
send_lapic_eoi();
|
send_lapic_eoi();
|
||||||
|
|
||||||
if (action != NULL && action->dev_handler != NULL) {
|
if (action != NULL) {
|
||||||
action->dev_handler(desc->irq, action->dev_data);
|
action(desc->irq, desc->priv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->state = IRQ_DESC_PENDING;
|
desc->state = IRQ_DESC_PENDING;
|
||||||
@ -498,7 +474,7 @@ int common_handler_edge(struct irq_desc *desc, __unused void *handler_data)
|
|||||||
|
|
||||||
int common_dev_handler_level(struct irq_desc *desc, __unused void *handler_data)
|
int common_dev_handler_level(struct irq_desc *desc, __unused void *handler_data)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *action = desc->action;
|
irq_action_t action = desc->action;
|
||||||
spinlock_rflags;
|
spinlock_rflags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -522,8 +498,8 @@ int common_dev_handler_level(struct irq_desc *desc, __unused void *handler_data)
|
|||||||
/* Send EOI to LAPIC/IOAPIC IRR */
|
/* Send EOI to LAPIC/IOAPIC IRR */
|
||||||
send_lapic_eoi();
|
send_lapic_eoi();
|
||||||
|
|
||||||
if (action != NULL && action->dev_handler != NULL) {
|
if (action != NULL) {
|
||||||
action->dev_handler(desc->irq, action->dev_data);
|
action(desc->irq, desc->priv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->state = IRQ_DESC_PENDING;
|
desc->state = IRQ_DESC_PENDING;
|
||||||
@ -536,13 +512,13 @@ int common_dev_handler_level(struct irq_desc *desc, __unused void *handler_data)
|
|||||||
/* no desc->irq_lock for quick handling local interrupt like lapic timer */
|
/* no desc->irq_lock for quick handling local interrupt like lapic timer */
|
||||||
int quick_handler_nolock(struct irq_desc *desc, __unused void *handler_data)
|
int quick_handler_nolock(struct irq_desc *desc, __unused void *handler_data)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *action = desc->action;
|
irq_action_t action = desc->action;
|
||||||
|
|
||||||
/* Send EOI to LAPIC/IOAPIC IRR */
|
/* Send EOI to LAPIC/IOAPIC IRR */
|
||||||
send_lapic_eoi();
|
send_lapic_eoi();
|
||||||
|
|
||||||
if (action != NULL && action->dev_handler != NULL) {
|
if (action != NULL) {
|
||||||
action->dev_handler(desc->irq, action->dev_data);
|
action(desc->irq, desc->priv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -564,45 +540,43 @@ void update_irq_handler(uint32_t irq, irq_handler_t func)
|
|||||||
spinlock_irqrestore_release(&desc->irq_lock);
|
spinlock_irqrestore_release(&desc->irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregister_handler_common(struct dev_handler_node *node)
|
void unregister_handler_common(uint32_t irq)
|
||||||
{
|
{
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
|
|
||||||
spinlock_rflags;
|
spinlock_rflags;
|
||||||
|
|
||||||
if (node == NULL) {
|
if (irq >= NR_IRQS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
desc = &irq_desc_array[irq];
|
||||||
dev_dbg(ACRN_DBG_IRQ, "[%s] %s irq%d vr:0x%x",
|
dev_dbg(ACRN_DBG_IRQ, "[%s] %s irq%d vr:0x%x",
|
||||||
__func__, node->name,
|
__func__, desc->name, irq, irq_to_vector(irq));
|
||||||
dev_to_irq(node),
|
|
||||||
dev_to_vector(node));
|
|
||||||
|
|
||||||
desc = node->desc;
|
|
||||||
spinlock_irqsave_obtain(&desc->irq_lock);
|
spinlock_irqsave_obtain(&desc->irq_lock);
|
||||||
|
|
||||||
desc->action = NULL;
|
desc->action = NULL;
|
||||||
|
desc->priv_data = NULL;
|
||||||
|
memset(desc->name, '\0', 32U);
|
||||||
|
|
||||||
spinlock_irqrestore_release(&desc->irq_lock);
|
spinlock_irqrestore_release(&desc->irq_lock);
|
||||||
irq_desc_try_free_vector(desc->irq);
|
irq_desc_try_free_vector(desc->irq);
|
||||||
free(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate IRQ with Vector from VECTOR_DYNAMIC_START ~ VECTOR_DYNAMIC_END
|
* Allocate IRQ with Vector from VECTOR_DYNAMIC_START ~ VECTOR_DYNAMIC_END
|
||||||
*/
|
*/
|
||||||
struct dev_handler_node*
|
int32_t normal_register_handler(uint32_t irq,
|
||||||
normal_register_handler(uint32_t irq,
|
irq_action_t func,
|
||||||
dev_handler_t func,
|
void *priv_data,
|
||||||
void *dev_data,
|
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
struct irq_request_info info;
|
struct irq_request_info info;
|
||||||
|
|
||||||
info.vector = VECTOR_INVALID;
|
info.vector = VECTOR_INVALID;
|
||||||
info.func = func;
|
info.func = func;
|
||||||
info.dev_data = dev_data;
|
info.priv_data = priv_data;
|
||||||
info.name = (char *)name;
|
info.name = (char *)name;
|
||||||
|
|
||||||
return common_register_handler(irq, &info);
|
return common_register_handler(irq, &info);
|
||||||
@ -614,22 +588,21 @@ normal_register_handler(uint32_t irq,
|
|||||||
* User can install same irq/isr on different CPU by call this function multiple
|
* User can install same irq/isr on different CPU by call this function multiple
|
||||||
* times
|
* times
|
||||||
*/
|
*/
|
||||||
struct dev_handler_node*
|
int32_t pri_register_handler(uint32_t irq,
|
||||||
pri_register_handler(uint32_t irq,
|
|
||||||
uint32_t vector,
|
uint32_t vector,
|
||||||
dev_handler_t func,
|
irq_action_t func,
|
||||||
void *dev_data,
|
void *priv_data,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
struct irq_request_info info;
|
struct irq_request_info info;
|
||||||
|
|
||||||
if (vector < VECTOR_FIXED_START || vector > VECTOR_FIXED_END) {
|
if (vector < VECTOR_FIXED_START || vector > VECTOR_FIXED_END) {
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.vector = vector;
|
info.vector = vector;
|
||||||
info.func = func;
|
info.func = func;
|
||||||
info.dev_data = dev_data;
|
info.priv_data = priv_data;
|
||||||
info.name = (char *)name;
|
info.name = (char *)name;
|
||||||
|
|
||||||
return common_register_handler(irq, &info);
|
return common_register_handler(irq, &info);
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
#include <hypervisor.h>
|
#include <hypervisor.h>
|
||||||
|
|
||||||
static struct dev_handler_node *notification_node;
|
static uint32_t notification_irq = IRQ_INVALID;
|
||||||
|
|
||||||
/* run in interrupt context */
|
/* run in interrupt context */
|
||||||
static int kick_notification(__unused int irq, __unused void *data)
|
static int kick_notification(__unused uint32_t irq, __unused void *data)
|
||||||
{
|
{
|
||||||
/* Notification vector does not require handling here, it's just used
|
/* Notification vector does not require handling here, it's just used
|
||||||
* to kick taget cpu out of non-root mode.
|
* to kick taget cpu out of non-root mode.
|
||||||
@ -17,26 +17,27 @@ static int kick_notification(__unused int irq, __unused void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int request_notification_irq(dev_handler_t func, void *data,
|
static int request_notification_irq(irq_action_t func, void *data,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
uint32_t irq = IRQ_INVALID; /* system allocate */
|
uint32_t irq = IRQ_INVALID; /* system allocate */
|
||||||
struct dev_handler_node *node = NULL;
|
int32_t retval;
|
||||||
|
|
||||||
if (notification_node != NULL) {
|
if (notification_irq != IRQ_INVALID) {
|
||||||
pr_info("%s, Notification vector already allocated on this CPU",
|
pr_info("%s, Notification vector already allocated on this CPU",
|
||||||
__func__);
|
__func__);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all cpu register the same notification vector */
|
/* all cpu register the same notification vector */
|
||||||
node = pri_register_handler(irq, VECTOR_NOTIFY_VCPU, func, data, name);
|
retval = pri_register_handler(irq, VECTOR_NOTIFY_VCPU, func, data, name);
|
||||||
if (node == NULL) {
|
if (retval < 0) {
|
||||||
pr_err("Failed to add notify isr");
|
pr_err("Failed to add notify isr");
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
update_irq_handler(dev_to_irq(node), quick_handler_nolock);
|
|
||||||
notification_node = node;
|
notification_irq = (uint32_t)retval;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,14 +59,13 @@ void setup_notification(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_PTIRQ, "NOTIFY: irq[%d] setup vector %x",
|
dev_dbg(ACRN_DBG_PTIRQ, "NOTIFY: irq[%d] setup vector %x",
|
||||||
dev_to_irq(notification_node),
|
notification_irq, irq_to_vector(notification_irq));
|
||||||
dev_to_vector(notification_node));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_notification(void)
|
static void cleanup_notification(void)
|
||||||
{
|
{
|
||||||
if (notification_node != NULL) {
|
if (notification_irq != IRQ_INVALID) {
|
||||||
unregister_handler_common(notification_node);
|
unregister_handler_common(notification_irq);
|
||||||
}
|
}
|
||||||
notification_node = NULL;
|
notification_irq = IRQ_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#define MIN_TIMER_PERIOD_US 500U
|
#define MIN_TIMER_PERIOD_US 500U
|
||||||
|
|
||||||
uint32_t tsc_khz = 0U;
|
uint32_t tsc_khz = 0U;
|
||||||
static struct dev_handler_node *timer_node;
|
|
||||||
static void run_timer(struct hv_timer *timer)
|
static void run_timer(struct hv_timer *timer)
|
||||||
{
|
{
|
||||||
/* deadline = 0 means stop timer, we should skip */
|
/* deadline = 0 means stop timer, we should skip */
|
||||||
@ -108,16 +108,13 @@ void del_timer(struct hv_timer *timer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int request_timer_irq(dev_handler_t func, const char *name)
|
static int request_timer_irq(irq_action_t func, const char *name)
|
||||||
{
|
{
|
||||||
if (timer_node != NULL) {
|
int32_t retval;
|
||||||
pr_err("Timer isr already added");
|
|
||||||
unregister_handler_common(timer_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_node = pri_register_handler(TIMER_IRQ, VECTOR_TIMER,
|
retval = pri_register_handler(TIMER_IRQ, VECTOR_TIMER,
|
||||||
func, NULL, name);
|
func, NULL, name);
|
||||||
if (timer_node != NULL) {
|
if (retval >= 0) {
|
||||||
update_irq_handler(TIMER_IRQ, quick_handler_nolock);
|
update_irq_handler(TIMER_IRQ, quick_handler_nolock);
|
||||||
} else {
|
} else {
|
||||||
pr_err("Failed to add timer isr");
|
pr_err("Failed to add timer isr");
|
||||||
@ -212,9 +209,8 @@ void timer_cleanup(void)
|
|||||||
{
|
{
|
||||||
uint16_t pcpu_id = get_cpu_id();
|
uint16_t pcpu_id = get_cpu_id();
|
||||||
|
|
||||||
if ((pcpu_id == BOOT_CPU_ID) && (timer_node != NULL)) {
|
if (pcpu_id == BOOT_CPU_ID) {
|
||||||
unregister_handler_common(timer_node);
|
unregister_handler_common(TIMER_IRQ);
|
||||||
timer_node = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +126,7 @@ struct dmar_drhd_rt {
|
|||||||
uint64_t ecap;
|
uint64_t ecap;
|
||||||
uint32_t gcmd; /* sw cache value of global cmd register */
|
uint32_t gcmd; /* sw cache value of global cmd register */
|
||||||
|
|
||||||
uint32_t irq;
|
uint32_t dmar_irq;
|
||||||
struct dev_handler_node *dmar_irq_node;
|
|
||||||
|
|
||||||
uint32_t max_domain_id;
|
uint32_t max_domain_id;
|
||||||
|
|
||||||
@ -185,6 +184,7 @@ static void register_hrhd_units(void)
|
|||||||
drhd_rt = calloc(1U, sizeof(struct dmar_drhd_rt));
|
drhd_rt = calloc(1U, sizeof(struct dmar_drhd_rt));
|
||||||
ASSERT(drhd_rt != NULL, "");
|
ASSERT(drhd_rt != NULL, "");
|
||||||
drhd_rt->drhd = &info->drhd_units[i];
|
drhd_rt->drhd = &info->drhd_units[i];
|
||||||
|
drhd_rt->dmar_irq = IRQ_INVALID;
|
||||||
dmar_register_hrhd(drhd_rt);
|
dmar_register_hrhd(drhd_rt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,7 +760,7 @@ static void fault_record_analysis(__unused uint64_t low, uint64_t high)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dmar_fault_handler(int irq, void *data)
|
static int dmar_fault_handler(uint32_t irq, void *data)
|
||||||
{
|
{
|
||||||
struct dmar_drhd_rt *dmar_uint = (struct dmar_drhd_rt *)data;
|
struct dmar_drhd_rt *dmar_uint = (struct dmar_drhd_rt *)data;
|
||||||
uint32_t fsr;
|
uint32_t fsr;
|
||||||
@ -819,26 +819,29 @@ static int dmar_fault_handler(int irq, void *data)
|
|||||||
static int dmar_setup_interrupt(struct dmar_drhd_rt *dmar_uint)
|
static int dmar_setup_interrupt(struct dmar_drhd_rt *dmar_uint)
|
||||||
{
|
{
|
||||||
uint32_t vector;
|
uint32_t vector;
|
||||||
|
int32_t retval;
|
||||||
|
|
||||||
if (dmar_uint->dmar_irq_node != NULL) {
|
if (dmar_uint->dmar_irq != IRQ_INVALID) {
|
||||||
dev_dbg(ACRN_DBG_IOMMU, "%s: irq already setup", __func__);
|
dev_dbg(ACRN_DBG_IOMMU, "%s: irq already setup", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmar_uint->dmar_irq_node = normal_register_handler(IRQ_INVALID,
|
retval = normal_register_handler(IRQ_INVALID,
|
||||||
dmar_fault_handler,
|
dmar_fault_handler,
|
||||||
dmar_uint,
|
dmar_uint,
|
||||||
"dmar_fault_event");
|
"dmar_fault_event");
|
||||||
|
|
||||||
if (dmar_uint->dmar_irq_node == NULL) {
|
if (retval < 0 ) {
|
||||||
pr_err("%s: fail to setup interrupt", __func__);
|
pr_err("%s: fail to setup interrupt", __func__);
|
||||||
return 1;
|
return retval;
|
||||||
|
} else {
|
||||||
|
dmar_uint->dmar_irq = (uint32_t)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector = dev_to_vector(dmar_uint->dmar_irq_node);
|
vector = irq_to_vector(dmar_uint->dmar_irq);
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_IOMMU, "alloc irq#%d vector#%d for dmar_uint",
|
dev_dbg(ACRN_DBG_IOMMU, "alloc irq#%d vector#%d for dmar_uint",
|
||||||
dev_to_irq(dmar_uint->dmar_irq_node), vector);
|
dmar_uint->dmar_irq, vector);
|
||||||
|
|
||||||
dmar_fault_msi_write(dmar_uint, vector);
|
dmar_fault_msi_write(dmar_uint, vector);
|
||||||
dmar_fault_event_unmask(dmar_uint);
|
dmar_fault_event_unmask(dmar_uint);
|
||||||
|
@ -118,7 +118,7 @@ release_all_entries(struct vm *vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* interrupt context */
|
/* interrupt context */
|
||||||
static int ptdev_interrupt_handler(__unused int irq, void *data)
|
static int ptdev_interrupt_handler(__unused uint32_t irq, void *data)
|
||||||
{
|
{
|
||||||
struct ptdev_remapping_info *entry =
|
struct ptdev_remapping_info *entry =
|
||||||
(struct ptdev_remapping_info *) data;
|
(struct ptdev_remapping_info *) data;
|
||||||
@ -131,14 +131,14 @@ static int ptdev_interrupt_handler(__unused int irq, void *data)
|
|||||||
void
|
void
|
||||||
ptdev_activate_entry(struct ptdev_remapping_info *entry, uint32_t phys_irq)
|
ptdev_activate_entry(struct ptdev_remapping_info *entry, uint32_t phys_irq)
|
||||||
{
|
{
|
||||||
struct dev_handler_node *node;
|
int32_t retval;
|
||||||
|
|
||||||
/* register and allocate host vector/irq */
|
/* register and allocate host vector/irq */
|
||||||
node = normal_register_handler(phys_irq, ptdev_interrupt_handler,
|
retval = normal_register_handler(phys_irq, ptdev_interrupt_handler,
|
||||||
(void *)entry, "dev assign");
|
(void *)entry, "dev assign");
|
||||||
|
|
||||||
ASSERT(node != NULL, "dev register failed");
|
ASSERT(retval >= 0, "dev register failed");
|
||||||
entry->node = node;
|
entry->allocated_pirq = (uint32_t)retval;
|
||||||
|
|
||||||
atomic_set32(&entry->active, ACTIVE_FLAG);
|
atomic_set32(&entry->active, ACTIVE_FLAG);
|
||||||
}
|
}
|
||||||
@ -150,8 +150,8 @@ ptdev_deactivate_entry(struct ptdev_remapping_info *entry)
|
|||||||
|
|
||||||
atomic_clear32(&entry->active, ACTIVE_FLAG);
|
atomic_clear32(&entry->active, ACTIVE_FLAG);
|
||||||
|
|
||||||
unregister_handler_common(entry->node);
|
unregister_handler_common(entry->allocated_pirq);
|
||||||
entry->node = NULL;
|
entry->allocated_pirq = IRQ_INVALID;
|
||||||
|
|
||||||
/* remove from softirq list if added */
|
/* remove from softirq list if added */
|
||||||
spinlock_irqsave_obtain(&softirq_dev_lock);
|
spinlock_irqsave_obtain(&softirq_dev_lock);
|
||||||
|
@ -23,14 +23,14 @@ enum irq_desc_state {
|
|||||||
IRQ_DESC_IN_PROCESS,
|
IRQ_DESC_IN_PROCESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*dev_handler_t)(int irq, void *dev_data);
|
typedef int (*irq_action_t)(uint32_t irq, void *dev_data);
|
||||||
struct irq_request_info {
|
struct irq_request_info {
|
||||||
/* vector set to 0xE0 ~ 0xFF for pri_register_handler
|
/* vector set to 0xE0 ~ 0xFF for pri_register_handler
|
||||||
* and set to VECTOR_INVALID for normal_register_handler
|
* and set to VECTOR_INVALID for normal_register_handler
|
||||||
*/
|
*/
|
||||||
uint32_t vector;
|
uint32_t vector;
|
||||||
dev_handler_t func;
|
irq_action_t func;
|
||||||
void *dev_data;
|
void *priv_data;
|
||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,46 +40,38 @@ struct irq_desc {
|
|||||||
enum irq_state used; /* this irq have assigned to device */
|
enum irq_state used; /* this irq have assigned to device */
|
||||||
enum irq_desc_state state; /* irq_desc status */
|
enum irq_desc_state state; /* irq_desc status */
|
||||||
uint32_t vector; /* assigned vector */
|
uint32_t vector; /* assigned vector */
|
||||||
void *handler_data; /* irq_handler private data */
|
|
||||||
int (*irq_handler)(struct irq_desc *irq_desc, void *handler_data);
|
int (*irq_handler)(struct irq_desc *irq_desc, void *handler_data);
|
||||||
struct dev_handler_node *action;
|
/* callback for irq flow handling */
|
||||||
|
irq_action_t action; /* callback registered from component */
|
||||||
|
void *priv_data; /* irq_action private data */
|
||||||
|
char name[32]; /* name of component */
|
||||||
|
|
||||||
spinlock_t irq_lock;
|
spinlock_t irq_lock;
|
||||||
uint64_t *irq_cnt; /* this irq cnt happened on CPUs */
|
uint64_t *irq_cnt; /* this irq cnt happened on CPUs */
|
||||||
uint64_t irq_lost_cnt;
|
uint64_t irq_lost_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dev_handler_node {
|
|
||||||
char name[32];
|
|
||||||
void *dev_data;
|
|
||||||
dev_handler_t dev_handler;
|
|
||||||
struct dev_handler_node *next;
|
|
||||||
struct irq_desc *desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t irq_mark_used(uint32_t irq);
|
uint32_t irq_mark_used(uint32_t irq);
|
||||||
|
|
||||||
uint32_t irq_desc_alloc_vector(uint32_t irq);
|
uint32_t irq_desc_alloc_vector(uint32_t irq);
|
||||||
void irq_desc_try_free_vector(uint32_t irq);
|
void irq_desc_try_free_vector(uint32_t irq);
|
||||||
|
|
||||||
uint32_t irq_to_vector(uint32_t irq);
|
uint32_t irq_to_vector(uint32_t irq);
|
||||||
uint32_t dev_to_irq(struct dev_handler_node *node);
|
|
||||||
uint32_t dev_to_vector(struct dev_handler_node *node);
|
|
||||||
|
|
||||||
struct dev_handler_node*
|
int32_t pri_register_handler(uint32_t irq,
|
||||||
pri_register_handler(uint32_t irq,
|
|
||||||
uint32_t vector,
|
uint32_t vector,
|
||||||
dev_handler_t func,
|
irq_action_t func,
|
||||||
void *dev_data,
|
void *priv_data,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
struct dev_handler_node*
|
int32_t normal_register_handler(uint32_t irq,
|
||||||
normal_register_handler(uint32_t irq,
|
irq_action_t func,
|
||||||
dev_handler_t func,
|
void *priv_data,
|
||||||
void *dev_data,
|
|
||||||
const char *name);
|
const char *name);
|
||||||
void unregister_handler_common(struct dev_handler_node *node);
|
|
||||||
|
void unregister_handler_common(uint32_t irq);
|
||||||
|
|
||||||
typedef int (*irq_handler_t)(struct irq_desc *desc, void *handler_data);
|
typedef int (*irq_handler_t)(struct irq_desc *desc, void *handler_data);
|
||||||
void update_irq_handler(uint32_t irq, irq_handler_t func);
|
void update_irq_handler(uint32_t irq, irq_handler_t func);
|
||||||
|
|
||||||
#endif /* COMMON_IRQ_H */
|
#endif /* COMMON_IRQ_H */
|
||||||
|
@ -51,7 +51,7 @@ struct ptdev_remapping_info {
|
|||||||
uint16_t phys_bdf; /* PCI bus:slot.func*/
|
uint16_t phys_bdf; /* PCI bus:slot.func*/
|
||||||
uint32_t active; /* 1=active, 0=inactive and to free*/
|
uint32_t active; /* 1=active, 0=inactive and to free*/
|
||||||
enum ptdev_intr_type type;
|
enum ptdev_intr_type type;
|
||||||
struct dev_handler_node *node;
|
uint32_t allocated_pirq;
|
||||||
struct list_head softirq_node;
|
struct list_head softirq_node;
|
||||||
struct list_head entry_node;
|
struct list_head entry_node;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user