From baa406108ab4e817c12fc21199e40d8c9e5d322b Mon Sep 17 00:00:00 2001 From: Alexander Kudryavtsev Date: Fri, 23 Sep 2011 23:16:10 +0400 Subject: [PATCH 07/32] Support for deferred EOI of passed through interrupts inside APIC. --- palacios/include/devices/apic.h | 3 ++- palacios/src/devices/apic.c | 16 +++++++++++++--- palacios/src/devices/io_apic.c | 3 ++- palacios/src/devices/pci_msi_router.c | 2 +- palacios/src/devices/pci_passthrough.c | 2 +- palacios/src/palacios/vmx.c | 4 ++-- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/palacios/include/devices/apic.h b/palacios/include/devices/apic.h index 4ddfc7c..375956f 100644 --- a/palacios/include/devices/apic.h +++ b/palacios/include/devices/apic.h @@ -24,6 +24,7 @@ #include +#include typedef enum {IPI_FIXED = 0, IPI_LOWEST_PRIO = 1, @@ -44,7 +45,7 @@ struct v3_gen_ipi { uint8_t dst; } __attribute__((packed)); -int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data); +int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data, struct irq_data irq_data); int v3_apic_raise_intr(struct v3_vm_info * vm, uint32_t irq, uint32_t dst, diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 508f221..7095dbf 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -256,6 +256,8 @@ struct apic_dev_state { v3_lock_t state_lock; + struct irq_data irq_data[256]; // per-vector IRQ data + struct apic_state apics[0]; } __attribute__((packed)); @@ -481,7 +483,7 @@ static int get_highest_irr(struct apic_state * apic) { -static int apic_do_eoi(struct apic_state * apic) { +static int apic_do_eoi(struct apic_dev_state * apic_dev, struct apic_state * apic) { int isr_irq = get_highest_isr(apic); if (isr_irq != -1) { @@ -489,11 +491,16 @@ static int apic_do_eoi(struct apic_state * apic) { int minor_offset = isr_irq & 0x00000007; uint8_t flag = 0x1 << minor_offset; uint8_t * svc_location = apic->int_svc_reg + major_offset; + struct irq_data irq_data = apic_dev->irq_data[isr_irq]; PrintDebug("apic %u: core ?: Received APIC EOI for IRQ %d\n", apic->lapic_id.val,isr_irq); *svc_location &= ~flag; + if(irq_data.flags.passed_through) + V3_ACK_IRQ(irq_data.host_vector); + + #ifdef V3_CONFIG_CRAY_XT if ((isr_irq == 238) || @@ -1406,7 +1413,7 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u // Action Registers case EOI_OFFSET: // do eoi - apic_do_eoi(apic); + apic_do_eoi(apic_dev, apic); break; case INT_CMD_LO_OFFSET: { @@ -1498,11 +1505,12 @@ static int apic_get_intr_number(struct guest_info * core, void * private_data) { -int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data) { +int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data, struct irq_data irq_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *) (((struct vm_device *)dev_data)->private_data); struct int_cmd_reg tmp_icr; + apic_dev->irq_data[ipi->vector] = irq_data; // zero out all the fields tmp_icr.val = 0; @@ -1734,6 +1742,8 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { apic_dev->num_apics = vm->num_cores; v3_lock_init(&(apic_dev->state_lock)); + memset(apic_dev->irq_data, 0, sizeof(apic_dev->irq_data)); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, apic_dev); if (dev == NULL) { diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index ce48ac8..e8f33c3 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -292,12 +292,13 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, struct ipi.trigger_mode = irq_entry->trig_mode; ipi.dst = irq_entry->dst_field; ipi.dst_shorthand = 0; + irq_data.irq = irq_entry->vec; PrintDebug("ioapic %u: IPI: vector 0x%x, mode 0x%x, logical 0x%x, trigger 0x%x, dst 0x%x, shorthand 0x%x\n", ioapic->ioapic_id.id, ipi.vector, ipi.mode, ipi.logical, ipi.trigger_mode, ipi.dst, ipi.dst_shorthand); // Need to add destination argument here... - if (v3_apic_send_ipi(vm, &ipi, ioapic->apic_dev_data) == -1) { + if (v3_apic_send_ipi(vm, &ipi, ioapic->apic_dev_data, irq_data) == -1) { PrintError("Error sending IPI to apic %d\n", ipi.dst); return -1; } diff --git a/palacios/src/devices/pci_msi_router.c b/palacios/src/devices/pci_msi_router.c index 7616e49..05ad81e 100644 --- a/palacios/src/devices/pci_msi_router.c +++ b/palacios/src/devices/pci_msi_router.c @@ -382,7 +382,7 @@ static int msi_raise_intr(struct v3_vm_info *vm, void *private_data, struct irq_ // "target vcpu_id %d, pcpu_id %d\n", irq, V3_Get_CPU(), ipi.dst, // ipi.dst < vm->num_cores ? vm->cores[ipi.dst].pcpu_id : -1); - if (v3_apic_send_ipi(vm, &ipi, state->apic_dev_data) == -1) { + if (v3_apic_send_ipi(vm, &ipi, state->apic_dev_data, irq_data) == -1) { PrintError("Error sending IPI to destination %d\n", ipi.dst); return -1; } diff --git a/palacios/src/devices/pci_passthrough.c b/palacios/src/devices/pci_passthrough.c index f4c207b..83407d2 100644 --- a/palacios/src/devices/pci_passthrough.c +++ b/palacios/src/devices/pci_passthrough.c @@ -680,7 +680,7 @@ static int irq_handler(struct v3_vm_info * vm, struct v3_interrupt * intr, void if(v3_pci_raise_qualified_irq(state->pci_bus, 0, state->pci_dev, iq)) return -1; - V3_ACK_IRQ(intr->irq); + //V3_ACK_IRQ(intr->irq); return 0; } diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index e2e6d4b..4ce78df 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -122,8 +122,8 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) vmx_state->sec_proc_ctrls.value = hw_info.sec_proc_ctrls.def_val; /* Print Control MSRs */ - PrintDebug("CR0 MSR: %p\n", (void *)(addr_t)hw_info.cr0.value); - PrintDebug("CR4 MSR: %p\n", (void *)(addr_t)hw_info.cr4.value); + //PrintDebug("CR0 MSR: %p\n", (void *)(addr_t)hw_info.cr0.value); + //PrintDebug("CR4 MSR: %p\n", (void *)(addr_t)hw_info.cr4.value); -- 1.7.5.4