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:
Yan, Like 2018-08-07 14:33:02 +08:00 committed by lijinxia
parent d773df9135
commit f6e45c9b13
8 changed files with 135 additions and 170 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;
} }
} }

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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;