X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fapic.c;h=9e636b619d91846553f411cdd1a6548aabfe903a;hb=25569fd796d1e1bb160b1b25ece9d4d3422720be;hp=3586794ec715838b5be6ac45f6fa01de0008df17;hpb=b8152adfb5d52ea2f3578b6eb38c32cc51b7269e;p=palacios.git diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 3586794..9e636b6 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -239,7 +239,7 @@ struct apic_state { uint8_t trig_mode_reg[32]; struct { - int (*ack)(struct guest_info * core, uint8_t irq, void * private_data); + int (*ack)(struct guest_info * core, uint32_t irq, void * private_data); void * private_data; } irq_ack_cbs[256]; @@ -424,6 +424,7 @@ static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num, *req_location |= flag; apic->irq_ack_cbs[irq_num].ack = ack; apic->irq_ack_cbs[irq_num].private_data = private_data; + return 1; } else { PrintDebug("apic %u: core %d: Interrupt not enabled... %.2x\n", @@ -471,7 +472,6 @@ static int add_apic_irq_entry(struct apic_state * apic, uint32_t irq_num, static void drain_irq_entries(struct apic_state * apic) { - while (1) { unsigned int flags = 0; struct irq_queue_entry * entry = NULL; @@ -505,7 +505,7 @@ static void drain_irq_entries(struct apic_state * apic) { static int get_highest_isr(struct apic_state * apic) { int i = 0, j = 0; - // We iterate backwards to find the highest priority + // We iterate backwards to find the highest priority in-service request for (i = 31; i >= 0; i--) { uint8_t * svc_major = apic->int_svc_reg + i; @@ -527,14 +527,15 @@ static int get_highest_isr(struct apic_state * apic) { static int get_highest_irr(struct apic_state * apic) { int i = 0, j = 0; - // We iterate backwards to find the highest priority + // We iterate backwards to find the highest priority enabled requested interrupt for (i = 31; i >= 0; i--) { uint8_t * req_major = apic->int_req_reg + i; - + uint8_t * en_major = apic->int_en_reg + i; + if ((*req_major) & 0xff) { for (j = 7; j >= 0; j--) { uint8_t flag = 0x1 << j; - if ((*req_major) & flag) { + if ((*req_major & *en_major) & flag) { return ((i * 8) + j); } } @@ -764,13 +765,10 @@ static int deliver_ipi(struct apic_state * src_apic, add_apic_irq_entry(dst_apic, ipi->vector, ipi->ack, ipi->private_data); -#ifdef V3_CONFIG_MULTITHREAD_OS if (dst_apic != src_apic) { PrintDebug(" non-local core with new interrupt, forcing it to exit now\n"); v3_interrupt_cpu(dst_core->vm_info, dst_core->pcpu_id, 0); } -#endif - break; } @@ -1880,6 +1878,12 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { apic_dev = (struct apic_dev_state *)V3_Malloc(sizeof(struct apic_dev_state) + sizeof(struct apic_state) * vm->num_cores); + + if (!apic_dev) { + PrintError("Failed to allocate space for APIC\n"); + return -1; + } + apic_dev->num_apics = vm->num_cores; v3_lock_init(&(apic_dev->state_lock));