From: Jack Lange Date: Wed, 4 May 2011 21:25:37 +0000 (-0500) Subject: separated virtual cores from physical cores X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a8627ddaccf49073eb04286c5ea4767e2903c351 separated virtual cores from physical cores --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index ee8e31c..4360a64 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -129,7 +129,10 @@ struct guest_info { v3_core_operating_mode_t core_run_state; /* the logical cpu on which this core runs */ - uint32_t cpu_id; + uint32_t pcpu_id; + + /* The virtual core # of this cpu (what the guest sees this core as) */ + uint32_t vcpu_id; }; diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 7f2eb45..5a2856a 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -28,6 +28,20 @@ #include +#include +#include + +/* The locking in this file is nasty. + * There are 3 different locking approaches that are taken, depending on the APIC operation + * 1. Queue locks. Actual irq insertions are done via queueing irq ops at the dest apic. + * The destination apic's core is responsible for draining the queue, and actually + * setting the vector table. + * 2. State locks. This is a standard lock taken when internal apic state is read/written. + * When an irq's destination is determined this lock is taken to examine the apic's + * addressability. + * 3. VM barrier lock. This is taken when actual VM core state is changed (via SIPI). + */ + #ifndef V3_CONFIG_DEBUG_APIC @@ -225,6 +239,9 @@ struct apic_state { struct v3_timer * timer; + v3_lock_t state_lock; + struct v3_queue irq_queue; + uint32_t eoi; @@ -304,6 +321,9 @@ static void init_apic_state(struct apic_state * apic, uint32_t id) { apic->spec_eoi.val = 0x00000000; + v3_init_queue(&(apic->irq_queue)); + + } @@ -312,9 +332,9 @@ static void init_apic_state(struct apic_state * apic, uint32_t id) { static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, void * priv_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)priv_data; - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); - PrintDebug("apic %u: core %u: MSR read\n", apic->lapic_id.val, core->cpu_id); + PrintDebug("apic %u: core %u: MSR read\n", apic->lapic_id.val, core->vcpu_id); dst->value = apic->base_addr; @@ -324,16 +344,16 @@ static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, v static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, void * priv_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)priv_data; - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); - struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->cpu_id, apic->base_addr); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); + struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, apic->base_addr); - PrintDebug("apic %u: core %u: MSR write\n", apic->lapic_id.val, core->cpu_id); + PrintDebug("apic %u: core %u: MSR write\n", apic->lapic_id.val, core->vcpu_id); if (old_reg == NULL) { // uh oh... PrintError("apic %u: core %u: APIC Base address region does not exit...\n", - apic->lapic_id.val, core->cpu_id); + apic->lapic_id.val, core->vcpu_id); return -1; } @@ -343,11 +363,11 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo apic->base_addr = src.value; - if (v3_hook_full_mem(core->vm_info, core->cpu_id, apic->base_addr, + if (v3_hook_full_mem(core->vm_info, core->vcpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev) == -1) { PrintError("apic %u: core %u: Could not hook new APIC Base address\n", - apic->lapic_id.val, core->cpu_id); + apic->lapic_id.val, core->vcpu_id); return -1; } @@ -358,10 +378,6 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo // irq_num is the bit offset into a 256 bit buffer... -// return values -// -1 = error -// 0 = OK, no interrupt needed now -// 1 = OK, interrupt needed now static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) { int major_offset = (irq_num & ~0x00000007) >> 3; int minor_offset = irq_num & 0x00000007; @@ -370,14 +386,14 @@ static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) { uint8_t flag = 0x1 << minor_offset; - if (irq_num <= 15 || irq_num>255) { + if (irq_num <= 15 || irq_num > 255) { PrintError("apic %u: core %d: Attempting to raise an invalid interrupt: %d\n", - apic->lapic_id.val, apic->core->cpu_id, irq_num); + apic->lapic_id.val, apic->core->vcpu_id, irq_num); return -1; } - PrintDebug("apic %u: core %d: Raising APIC IRQ %d\n", apic->lapic_id.val, apic->core->cpu_id, irq_num); + PrintDebug("apic %u: core %d: Raising APIC IRQ %d\n", apic->lapic_id.val, apic->core->vcpu_id, irq_num); if (*req_location & flag) { PrintDebug("Interrupt %d coallescing\n", irq_num); @@ -389,7 +405,7 @@ static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) { return 1; } else { PrintDebug("apic %u: core %d: Interrupt not enabled... %.2x\n", - apic->lapic_id.val, apic->core->cpu_id,*en_location); + apic->lapic_id.val, apic->core->vcpu_id, *en_location); } return 0; @@ -540,13 +556,13 @@ static inline int should_deliver_cluster_ipi(struct guest_info * dst_core, ((mda & 0x0f) & (dst_apic->log_dst.dst_log_id & 0x0f)) ) { /* I am in the set) */ PrintDebug("apic %u core %u: accepting clustered IRQ (mda 0x%x == log_dst 0x%x)\n", - dst_apic->lapic_id.val, dst_core->cpu_id, mda, + dst_apic->lapic_id.val, dst_core->vcpu_id, mda, dst_apic->log_dst.dst_log_id); return 1; } else { PrintDebug("apic %u core %u: rejecting clustered IRQ (mda 0x%x != log_dst 0x%x)\n", - dst_apic->lapic_id.val, dst_core->cpu_id, mda, + dst_apic->lapic_id.val, dst_core->vcpu_id, mda, dst_apic->log_dst.dst_log_id); return 0; } @@ -558,7 +574,7 @@ static inline int should_deliver_flat_ipi(struct guest_info * dst_core, if (dst_apic->log_dst.dst_log_id & mda) { // I am in the set PrintDebug("apic %u core %u: accepting flat IRQ (mda 0x%x == log_dst 0x%x)\n", - dst_apic->lapic_id.val, dst_core->cpu_id, mda, + dst_apic->lapic_id.val, dst_core->vcpu_id, mda, dst_apic->log_dst.dst_log_id); return 1; @@ -566,7 +582,7 @@ static inline int should_deliver_flat_ipi(struct guest_info * dst_core, } else { PrintDebug("apic %u core %u: rejecting flat IRQ (mda 0x%x != log_dst 0x%x)\n", - dst_apic->lapic_id.val, dst_core->cpu_id, mda, + dst_apic->lapic_id.val, dst_core->vcpu_id, mda, dst_apic->log_dst.dst_log_id); return 0; } @@ -598,7 +614,7 @@ static int should_deliver_ipi(struct guest_info * dst_core, } else { PrintError("apic %u core %u: invalid destination format register value 0x%x for logical mode delivery.\n", - dst_apic->lapic_id.val, dst_core->cpu_id, dst_apic->dst_fmt.model); + dst_apic->lapic_id.val, dst_core->vcpu_id, dst_apic->dst_fmt.model); return -1; } } @@ -622,27 +638,17 @@ static int deliver_ipi(struct apic_state * src_apic, int do_xcall; - PrintDebug("delivering IRQ %d to core %u\n", vector, dst_core->cpu_id); + PrintDebug("delivering IRQ %d to core %u\n", vector, dst_core->vcpu_id); do_xcall = activate_apic_irq(dst_apic, vector); - if (do_xcall < 0) { - PrintError("Failed to activate apic irq!\n"); - return -1; - } - if (do_xcall && (dst_apic != src_apic)) { - // Assume core # is same as logical processor for now - // TODO FIX THIS FIX THIS - // THERE SHOULD BE: guestapicid->virtualapicid map, - // cpu_id->logical processor map - // host maitains logical proc->phsysical proc + + if (dst_apic != src_apic) { PrintDebug(" non-local core with new interrupt, forcing it to exit now\n"); #ifdef V3_CONFIG_MULTITHREAD_OS - v3_interrupt_cpu(dst_core->vm_info, dst_core->cpu_id, 0); -#else - V3_ASSERT(0); + v3_interrupt_cpu(dst_core->vm_info, dst_core->pcpu_id, 0); #endif } @@ -650,14 +656,14 @@ static int deliver_ipi(struct apic_state * src_apic, } case APIC_INIT_DELIVERY: { - PrintDebug(" INIT delivery to core %u\n", dst_core->cpu_id); + PrintDebug(" INIT delivery to core %u\n", dst_core->vcpu_id); // TODO: any APIC reset on dest core (shouldn't be needed, but not sure...) // Sanity check if (dst_apic->ipi_state != INIT_ST) { PrintError(" Warning: core %u is not in INIT state (mode = %d), ignored (assuming this is the deassert)\n", - dst_core->cpu_id, dst_apic->ipi_state); + dst_core->vcpu_id, dst_apic->ipi_state); // Only a warning, since INIT INIT SIPI is common break; } @@ -680,7 +686,7 @@ static int deliver_ipi(struct apic_state * src_apic, // Sanity check if (dst_apic->ipi_state != SIPI) { PrintError(" core %u is not in SIPI state (mode = %d), ignored!\n", - dst_core->cpu_id, dst_apic->ipi_state); + dst_core->vcpu_id, dst_apic->ipi_state); break; } @@ -700,7 +706,7 @@ static int deliver_ipi(struct apic_state * src_apic, dst_core->segments.cs.base = vector << 12; PrintDebug(" SIPI delivery (0x%x -> 0x%x:0x0) to core %u\n", - vector, dst_core->segments.cs.selector, dst_core->cpu_id); + vector, dst_core->segments.cs.selector, dst_core->vcpu_id); // Maybe need to adjust the APIC? // We transition the target core to SIPI state @@ -730,14 +736,14 @@ static struct apic_state * find_physical_apic(struct apic_dev_state *apic_dev, s { int i; - if (icr->dst >0 && icr->dst < apic_dev->num_apics) { + if ( (icr->dst > 0) && (icr->dst < apic_dev->num_apics) ) { // see if it simply is the core id if (apic_dev->apics[icr->dst].lapic_id.val == icr->dst) { return &(apic_dev->apics[icr->dst]); } } - for (i=0;inum_apics;i++) { + for (i = 0; i < apic_dev->num_apics; i++) { if (apic_dev->apics[i].lapic_id.val == icr->dst) { return &(apic_dev->apics[i]); } @@ -769,9 +775,9 @@ static int route_ipi(struct apic_dev_state * apic_dev, case APIC_SHORTHAND_NONE: // no shorthand if (icr->dst_mode == APIC_DEST_PHYSICAL) { - dest_apic=find_physical_apic(apic_dev,icr); + dest_apic = find_physical_apic(apic_dev, icr); - if (dest_apic==NULL) { + if (dest_apic == NULL) { PrintError("apic: Attempted send to unregistered apic id=%u\n", icr->dst); return -1; } @@ -783,29 +789,32 @@ static int route_ipi(struct apic_dev_state * apic_dev, } - V3_Print("apic: done\n"); - + PrintDebug("apic: done\n"); } else if (icr->dst_mode == APIC_DEST_LOGICAL) { - if (icr->del_mode!=APIC_LOWEST_DELIVERY ) { + if (icr->del_mode != APIC_LOWEST_DELIVERY) { + int i; + uint8_t mda = icr->dst; + // logical, but not lowest priority // we immediately trigger // fixed, smi, reserved, nmi, init, sipi, etc - int i; - - uint8_t mda = icr->dst; + for (i = 0; i < apic_dev->num_apics; i++) { + int del_flag = 0; dest_apic = &(apic_dev->apics[i]); - int del_flag = should_deliver_ipi(dest_apic->core, dest_apic, mda); + del_flag = should_deliver_ipi(dest_apic->core, dest_apic, mda); if (del_flag == -1) { + PrintError("apic: Error checking delivery mode\n"); return -1; } else if (del_flag == 1) { + if (deliver_ipi(src_apic, dest_apic, icr->vec, icr->del_mode) == -1) { PrintError("apic: Error: Could not deliver IPI\n"); @@ -814,11 +823,12 @@ static int route_ipi(struct apic_dev_state * apic_dev, } } } else { //APIC_LOWEST_DELIVERY - // logical, lowest priority int i; struct apic_state * cur_best_apic = NULL; uint8_t mda = icr->dst; + // logical, lowest priority + for (i = 0; i < apic_dev->num_apics; i++) { int del_flag = 0; @@ -832,7 +842,7 @@ static int route_ipi(struct apic_dev_state * apic_dev, return -1; } else if (del_flag == 1) { // update priority for lowest priority scan - if (!cur_best_apic) { + if (cur_best_apic == 0) { cur_best_apic = dest_apic; } else if (dest_apic->task_prio.val < cur_best_apic->task_prio.val) { cur_best_apic = dest_apic; @@ -872,6 +882,7 @@ static int route_ipi(struct apic_dev_state * apic_dev, } } else if (icr->dst_mode == APIC_DEST_LOGICAL) { /* logical delivery */ PrintError("apic: use of logical delivery in self (untested)\n"); + if (deliver_ipi(src_apic, src_apic, icr->vec, icr->del_mode) == -1) { PrintError("apic: Could not deliver IPI to self (logical)\n"); return -1; @@ -911,18 +922,18 @@ static int route_ipi(struct apic_dev_state * apic_dev, // External function, expected to acquire lock on apic static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); addr_t reg_addr = guest_addr - apic->base_addr; struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); uint32_t val = 0; PrintDebug("apic %u: core %u: at %p: Read apic address space (%p)\n", - apic->lapic_id.val, core->cpu_id, apic, (void *)guest_addr); + apic->lapic_id.val, core->vcpu_id, apic, (void *)guest_addr); if (msr->apic_enable == 0) { PrintError("apic %u: core %u: Read from APIC address space with disabled APIC, apic msr=0x%llx\n", - apic->lapic_id.val, core->cpu_id, apic->base_addr_msr.value); + apic->lapic_id.val, core->vcpu_id, apic->base_addr_msr.value); return -1; } @@ -1135,7 +1146,7 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui default: PrintError("apic %u: core %u: Read from Unhandled APIC Register: %x (getting zero)\n", - apic->lapic_id.val, core->cpu_id, (uint32_t)reg_addr); + apic->lapic_id.val, core->vcpu_id, (uint32_t)reg_addr); return -1; } @@ -1158,12 +1169,12 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui } else { PrintError("apic %u: core %u: Invalid apic read length (%d)\n", - apic->lapic_id.val, core->cpu_id, length); + apic->lapic_id.val, core->vcpu_id, length); return -1; } PrintDebug("apic %u: core %u: Read finished (val=%x)\n", - apic->lapic_id.val, core->cpu_id, *(uint32_t *)dst); + apic->lapic_id.val, core->vcpu_id, *(uint32_t *)dst); return length; } @@ -1174,27 +1185,27 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui */ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); addr_t reg_addr = guest_addr - apic->base_addr; struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); uint32_t op_val = *(uint32_t *)src; PrintDebug("apic %u: core %u: at %p and priv_data is at %p\n", - apic->lapic_id.val, core->cpu_id, apic, priv_data); + apic->lapic_id.val, core->vcpu_id, apic, priv_data); PrintDebug("apic %u: core %u: write to address space (%p) (val=%x)\n", - apic->lapic_id.val, core->cpu_id, (void *)guest_addr, *(uint32_t *)src); + apic->lapic_id.val, core->vcpu_id, (void *)guest_addr, *(uint32_t *)src); if (msr->apic_enable == 0) { PrintError("apic %u: core %u: Write to APIC address space with disabled APIC, apic msr=0x%llx\n", - apic->lapic_id.val, core->cpu_id, apic->base_addr_msr.value); + apic->lapic_id.val, core->vcpu_id, apic->base_addr_msr.value); return -1; } if (length != 4) { PrintError("apic %u: core %u: Invalid apic write length (%d)\n", - apic->lapic_id.val, length, core->cpu_id); + apic->lapic_id.val, length, core->vcpu_id); return -1; } @@ -1230,14 +1241,14 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u case EXT_APIC_FEATURE_OFFSET: PrintError("apic %u: core %u: Attempting to write to read only register %p (error)\n", - apic->lapic_id.val, core->cpu_id, (void *)reg_addr); + apic->lapic_id.val, core->vcpu_id, (void *)reg_addr); break; // Data registers case APIC_ID_OFFSET: //V3_Print("apic %u: core %u: my id is being changed to %u\n", - // apic->lapic_id.val, core->cpu_id, op_val); + // apic->lapic_id.val, core->vcpu_id, op_val); apic->lapic_id.val = op_val; break; @@ -1246,7 +1257,7 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u break; case LDR_OFFSET: PrintDebug("apic %u: core %u: setting log_dst.val to 0x%x\n", - apic->lapic_id.val, core->cpu_id, op_val); + apic->lapic_id.val, core->vcpu_id, op_val); apic->log_dst.val = op_val; break; case DFR_OFFSET: @@ -1344,18 +1355,19 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u tmp_icr = apic->int_cmd; // V3_Print("apic %u: core %u: sending cmd 0x%llx to apic %u\n", - // apic->lapic_id.val, core->cpu_id, + // apic->lapic_id.val, core->vcpu_id, // apic->int_cmd.val, apic->int_cmd.dst); if (route_ipi(apic_dev, apic, &tmp_icr) == -1) { PrintError("IPI Routing failure\n"); return -1; } + break; } case INT_CMD_HI_OFFSET: { apic->int_cmd.hi = op_val; - V3_Print("apic %u: core %u: writing command high=0x%x\n", apic->lapic_id.val, core->cpu_id,apic->int_cmd.hi); + V3_Print("apic %u: core %u: writing command high=0x%x\n", apic->lapic_id.val, core->vcpu_id,apic->int_cmd.hi); break; } @@ -1364,12 +1376,12 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u case SEOI_OFFSET: default: PrintError("apic %u: core %u: Write to Unhandled APIC Register: %x (ignored)\n", - apic->lapic_id.val, core->cpu_id, (uint32_t)reg_addr); + apic->lapic_id.val, core->vcpu_id, (uint32_t)reg_addr); return -1; } - PrintDebug("apic %u: core %u: Write finished\n", apic->lapic_id.val, core->cpu_id); + PrintDebug("apic %u: core %u: Write finished\n", apic->lapic_id.val, core->vcpu_id); return length; @@ -1382,11 +1394,14 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u static int apic_intr_pending(struct guest_info * core, void * private_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); + + // drain irq QUEUE + int req_irq = get_highest_irr(apic); int svc_irq = get_highest_isr(apic); - // PrintDebug("apic %u: core %u: req_irq=%d, svc_irq=%d\n",apic->lapic_id.val,info->cpu_id,req_irq,svc_irq); + // PrintDebug("apic %u: core %u: req_irq=%d, svc_irq=%d\n",apic->lapic_id.val,info->vcpu_id,req_irq,svc_irq); if ((req_irq >= 0) && (req_irq > svc_irq)) { @@ -1400,7 +1415,7 @@ static int apic_intr_pending(struct guest_info * core, void * private_data) { static int apic_get_intr_number(struct guest_info * core, void * private_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); int req_irq = get_highest_irr(apic); int svc_irq = get_highest_isr(apic); @@ -1466,7 +1481,7 @@ int v3_apic_raise_intr(struct v3_vm_info * vm, uint32_t irq, uint32_t dst, void static int apic_begin_irq(struct guest_info * core, void * private_data, int irq) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(private_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); int major_offset = (irq & ~0x00000007) >> 3; int minor_offset = irq & 0x00000007; uint8_t *req_location = apic->int_req_reg + major_offset; @@ -1481,7 +1496,7 @@ static int apic_begin_irq(struct guest_info * core, void * private_data, int irq } else { // do nothing... //PrintDebug("apic %u: core %u: begin irq for %d ignored since I don't own it\n", - // apic->lapic_id.val, core->cpu_id, irq); + // apic->lapic_id.val, core->vcpu_id, irq); } return 0; @@ -1497,7 +1512,7 @@ static void apic_update_time(struct guest_info * core, uint64_t cpu_cycles, uint64_t cpu_freq, void * priv_data) { struct apic_dev_state * apic_dev = (struct apic_dev_state *)(priv_data); - struct apic_state * apic = &(apic_dev->apics[core->cpu_id]); + struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); // The 32 bit GCC runtime is a pile of shit #ifdef __V3_64BIT__ @@ -1516,7 +1531,7 @@ static void apic_update_time(struct guest_info * core, if ((apic->tmr_init_cnt == 0) || ( (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_ONESHOT) && (apic->tmr_cur_cnt == 0))) { - //PrintDebug("apic %u: core %u: APIC timer not yet initialized\n",apic->lapic_id.val,info->cpu_id); + //PrintDebug("apic %u: core %u: APIC timer not yet initialized\n",apic->lapic_id.val,info->vcpu_id); return; } @@ -1548,7 +1563,7 @@ static void apic_update_time(struct guest_info * core, break; default: PrintError("apic %u: core %u: Invalid Timer Divider configuration\n", - apic->lapic_id.val, core->cpu_id); + apic->lapic_id.val, core->vcpu_id); return; } @@ -1563,18 +1578,18 @@ static void apic_update_time(struct guest_info * core, // raise irq PrintDebug("apic %u: core %u: Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", - apic->lapic_id.val, core->cpu_id, + apic->lapic_id.val, core->vcpu_id, apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num); if (apic_intr_pending(core, priv_data)) { PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", - apic->lapic_id.val, core->cpu_id, + apic->lapic_id.val, core->vcpu_id, apic_get_intr_number(core, priv_data)); } if (activate_internal_irq(apic, APIC_TMR_INT) == -1) { PrintError("apic %u: core %u: Could not raise Timer interrupt\n", - apic->lapic_id.val, core->cpu_id); + apic->lapic_id.val, core->vcpu_id); } if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) { @@ -1673,7 +1688,7 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } - v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev); + v3_hook_full_mem(vm, core->vcpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev); PrintDebug("apic %u: (setup device): done, my id is %u\n", i, apic->lapic_id.val); } diff --git a/palacios/src/extensions/ext_inspector.c b/palacios/src/extensions/ext_inspector.c index 7b89a91..5a440c1 100644 --- a/palacios/src/extensions/ext_inspector.c +++ b/palacios/src/extensions/ext_inspector.c @@ -53,7 +53,7 @@ static int init_inspector_core(struct guest_info * core, void * priv_data) { struct v3_inspector_state * vm_state = priv_data; char core_name[50]; - snprintf(core_name, 50, "core.%d", core->cpu_id); + snprintf(core_name, 50, "core.%d", core->vcpu_id); { struct v3_mtree * core_node = v3_mtree_create_subtree(&(vm_state->state_tree), core_name); diff --git a/palacios/src/extensions/ext_vtime.c b/palacios/src/extensions/ext_vtime.c index 665d6be..6fd9931 100644 --- a/palacios/src/extensions/ext_vtime.c +++ b/palacios/src/extensions/ext_vtime.c @@ -155,7 +155,7 @@ static int init() { if (khz) { time_state->guest_cpu_freq = atoi(khz); PrintDebug("Core %d CPU frequency requested at %d khz.\n", - info->cpu_id, time_state->guest_cpu_freq); + info->pcpu_id, time_state->guest_cpu_freq); } if ( (khz == NULL) || diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_cache_32.h b/palacios/src/palacios/mmu/vmm_shdw_pg_cache_32.h index 2aae928..fab26fd 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_cache_32.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_cache_32.h @@ -277,7 +277,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * core, addr_t fault pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]); addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_pa); if (shdw_reg == NULL) { // Inject a machine check in the guest @@ -459,7 +459,7 @@ static int handle_4MB_shadow_pagefault_pte_32(struct guest_info * core, PrintDebug("Handling 4MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_32.h b/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_32.h index 91a77c6..8a2e094 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_32.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_32.h @@ -274,7 +274,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * core, addr_t fault pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]); addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_pa); if (shdw_reg == NULL) { // Inject a machine check in the guest @@ -322,7 +322,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * core, addr_t fault if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) { - addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_pa); + addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->vcpu_id, guest_pa); shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa); @@ -408,7 +408,7 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * core, PrintDebug("Handling 4MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { @@ -431,7 +431,7 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * core, if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) { - addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_fault_pa); + addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->vcpu_id, guest_fault_pa); shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa); diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_64.h b/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_64.h index 6ada76b..93a84eb 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_64.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_kvm_64.h @@ -534,7 +534,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * core, addr_t fault PrintDebug("Handling PTE fault\n"); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_pa); @@ -607,7 +607,7 @@ pte_noerror: int inherited_ar_user = ((inherited_ar & PT_USER_MASK) == PT_USER_MASK) ? 1 : 0; int inherited_ar_writable = ((inherited_ar & PT_WRITABLE_MASK) == PT_WRITABLE_MASK) ? 1 : 0; - addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_pa); + addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->vcpu_id, guest_pa); shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa); @@ -722,7 +722,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * core, PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, guest_fault_pa); int fixed = 0; int write_pt = 0; @@ -743,7 +743,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * core, if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) { - addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_fault_pa); + addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->vcpu_id, guest_fault_pa); shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa); diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_32.h b/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_32.h index bb5de94..3b745af 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_32.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_32.h @@ -205,7 +205,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]); addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_pa); if (shdw_reg == NULL) { // Inject a machine check in the guest @@ -430,7 +430,7 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * info, PrintDebug("Handling 4MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_64.h b/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_64.h index b4068b2..cb29966 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_64.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_swapbypass_64.h @@ -408,7 +408,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault PrintDebug("Handling PTE fault\n"); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_pa); @@ -543,7 +543,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_32.h b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_32.h index b3f4e43..e638056 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_32.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_32.h @@ -218,7 +218,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault pte32_t * shadow_pte = (pte32_t *)&(shadow_pt[PTE32_INDEX(fault_addr)]); addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) + PAGE_OFFSET(fault_addr); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_pa); if (shdw_reg == NULL) { // Inject a machine check in the guest @@ -353,7 +353,7 @@ static int handle_4MB_shadow_pagefault_pte_32(struct guest_info * info, PrintDebug("Handling 4MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { @@ -448,7 +448,7 @@ static int handle_4MB_shadow_pagefault_pde_32(struct guest_info * info, PrintDebug("Handling 4MB fault with large page (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("LargeShadowPDE=%p, LargeGuestPDE=%p\n", large_shadow_pde, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { diff --git a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h index 38aebe6..4f31b7f 100644 --- a/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h +++ b/palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h @@ -426,7 +426,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault PrintDebug("Handling PTE fault\n"); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_pa); @@ -558,7 +558,7 @@ static int handle_2MB_shadow_pagefault_pde_64(struct guest_info * info, PrintDebug("Handling 2MB fault with large page (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("LargeShadowPDE=%p, LargeGuestPDE=%p\n", large_shadow_pde, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { // Inject a machine check in the guest @@ -640,7 +640,7 @@ static int handle_2MB_shadow_pagefault_pte_64(struct guest_info * info, PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code); PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde); - struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa); + struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->vcpu_id, guest_fault_pa); if (shdw_reg == NULL) { diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index bb5b525..980ce99 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -587,29 +587,31 @@ int v3_start_svm_guest(struct guest_info * info) { // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); // vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); - PrintDebug("Starting SVM core %u\n", info->cpu_id); + PrintDebug("Starting SVM core %u (on logical core %u)\n", info->vcpu_id, info->pcpu_id); - if (info->cpu_id == 0) { + if (info->vcpu_id == 0) { info->core_run_state = CORE_RUNNING; info->vm_info->run_state = VM_RUNNING; } else { - PrintDebug("SVM core %u: Waiting for core initialization\n", info->cpu_id); + PrintDebug("SVM core %u (on %u): Waiting for core initialization\n", info->vcpu_id, info->pcpu_id); while (info->core_run_state == CORE_STOPPED) { v3_yield(info); - //PrintDebug("SVM core %u: still waiting for INIT\n",info->cpu_id); + //PrintDebug("SVM core %u: still waiting for INIT\n", info->vcpu_id); } - PrintDebug("SVM core %u initialized\n", info->cpu_id); + PrintDebug("SVM core %u(on %u) initialized\n", info->vcpu_id, info->pcpu_id); } - PrintDebug("SVM core %u: I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n", - info->cpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base), + PrintDebug("SVM core %u(on %u): I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n", + info->vcpu_id, info->pcpu_id, + info->segments.cs.selector, (void *)(info->segments.cs.base), info->segments.cs.limit, (void *)(info->rip)); - PrintDebug("SVM core %u: Launching SVM VM (vmcb=%p)\n", info->cpu_id, (void *)info->vmm_data); + PrintDebug("SVM core %u: Launching SVM VM (vmcb=%p) (on cpu %u)\n", + info->vcpu_id, (void *)info->vmm_data, info->pcpu_id); //PrintDebugVMCB((vmcb_t*)(info->vmm_data)); v3_start_time(info); @@ -628,17 +630,17 @@ int v3_start_svm_guest(struct guest_info * info) { info->vm_info->run_state = VM_ERROR; - V3_Print("SVM core %u: SVM ERROR!!\n", info->cpu_id); + V3_Print("SVM core %u: SVM ERROR!!\n", info->vcpu_id); v3_print_guest_state(info); - V3_Print("SVM core %u: SVM Exit Code: %p\n", info->cpu_id, (void *)(addr_t)guest_ctrl->exit_code); + V3_Print("SVM core %u: SVM Exit Code: %p\n", info->vcpu_id, (void *)(addr_t)guest_ctrl->exit_code); - V3_Print("SVM core %u: exit_info1 low = 0x%.8x\n", info->cpu_id, *(uint_t*)&(guest_ctrl->exit_info1)); - V3_Print("SVM core %u: exit_info1 high = 0x%.8x\n", info->cpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4)); + V3_Print("SVM core %u: exit_info1 low = 0x%.8x\n", info->vcpu_id, *(uint_t*)&(guest_ctrl->exit_info1)); + V3_Print("SVM core %u: exit_info1 high = 0x%.8x\n", info->vcpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4)); - V3_Print("SVM core %u: exit_info2 low = 0x%.8x\n", info->cpu_id, *(uint_t*)&(guest_ctrl->exit_info2)); - V3_Print("SVM core %u: exit_info2 high = 0x%.8x\n", info->cpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4)); + V3_Print("SVM core %u: exit_info2 low = 0x%.8x\n", info->vcpu_id, *(uint_t*)&(guest_ctrl->exit_info2)); + V3_Print("SVM core %u: exit_info2 high = 0x%.8x\n", info->vcpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4)); linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); @@ -648,9 +650,9 @@ int v3_start_svm_guest(struct guest_info * info) { v3_gva_to_hva(info, linear_addr, &host_addr); } - V3_Print("SVM core %u: Host Address of rip = 0x%p\n", info->cpu_id, (void *)host_addr); + V3_Print("SVM core %u: Host Address of rip = 0x%p\n", info->vcpu_id, (void *)host_addr); - V3_Print("SVM core %u: Instr (15 bytes) at %p:\n", info->cpu_id, (void *)host_addr); + V3_Print("SVM core %u: Instr (15 bytes) at %p:\n", info->vcpu_id, (void *)host_addr); v3_dump_mem((uint8_t *)host_addr, 15); v3_print_stack(info); diff --git a/palacios/src/palacios/vm_guest_mem.c b/palacios/src/palacios/vm_guest_mem.c index ca6c601..8cc497a 100644 --- a/palacios/src/palacios/vm_guest_mem.c +++ b/palacios/src/palacios/vm_guest_mem.c @@ -64,7 +64,7 @@ int v3_hpa_to_hva(addr_t hpa, addr_t * hva) { } int v3_gpa_to_hpa(struct guest_info * info, addr_t gpa, addr_t * hpa) { - struct v3_mem_region * reg = v3_get_mem_region(info->vm_info, info->cpu_id, gpa); + struct v3_mem_region * reg = v3_get_mem_region(info->vm_info, info->vcpu_id, gpa); if (reg == NULL) { PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n", diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index f3bce6f..7e77412 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -209,8 +209,8 @@ static int start_core(void * p) struct guest_info * core = (struct guest_info *)p; - PrintDebug("virtual core %u: in start_core (RIP=%p)\n", - core->cpu_id, (void *)(addr_t)core->rip); + PrintDebug("virtual core %u (on logical core %u): in start_core (RIP=%p)\n", + core->vcpu_id, core->pcpu_id, (void *)(addr_t)core->rip); switch (v3_cpu_types[0]) { #ifdef V3_CONFIG_SVM @@ -292,7 +292,6 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { i--; // We reset the logical core idx. Not strictly necessary I guess... } else { - /* This assumes that the core 0 thread has been mapped to physical core 0 */ if (i == V3_Get_CPU()) { // We skip the local CPU because it is reserved for vcore 0 continue; @@ -327,6 +326,7 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { core_idx, start_core, core, core->exec_name); // TODO: actually manage these threads instead of just launching them + core->pcpu_id = core_idx; core_thread = V3_CREATE_THREAD_ON_CPU(core_idx, start_core, core, core->exec_name); if (core_thread == NULL) { @@ -341,6 +341,8 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { sprintf(vm->cores[0].exec_name, "%s", vm->name); + vm->cores[0].pcpu_id = V3_Get_CPU(); + if (start_core(&(vm->cores[0])) != 0) { PrintError("Error starting VM core 0\n"); v3_stop_vm(vm); diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index bb6f985..8d348e6 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -492,7 +492,7 @@ struct v3_vm_info * v3_config_guest(void * cfg_blob, void * priv_data) { for (i = 0; i < vm->num_cores; i++) { struct guest_info * info = &(vm->cores[i]); - info->cpu_id = i; + info->vcpu_id = i; info->vm_info = vm; info->core_cfg_data = per_core_cfg; diff --git a/palacios/src/palacios/vmm_direct_paging_32.h b/palacios/src/palacios/vmm_direct_paging_32.h index e90c3da..ac6f054 100644 --- a/palacios/src/palacios/vmm_direct_paging_32.h +++ b/palacios/src/palacios/vmm_direct_paging_32.h @@ -39,7 +39,7 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info, int pde_index = PDE32_INDEX(fault_addr); int pte_index = PTE32_INDEX(fault_addr); - struct v3_mem_region * region = v3_get_mem_region(info->vm_info, info->cpu_id, fault_addr); + struct v3_mem_region * region = v3_get_mem_region(info->vm_info, info->vcpu_id, fault_addr); if (region == NULL) { PrintError("Invalid region in passthrough page fault 32, addr=%p\n", diff --git a/palacios/src/palacios/vmm_direct_paging_32pae.h b/palacios/src/palacios/vmm_direct_paging_32pae.h index a2bb71d..06e5bb4 100644 --- a/palacios/src/palacios/vmm_direct_paging_32pae.h +++ b/palacios/src/palacios/vmm_direct_paging_32pae.h @@ -40,7 +40,7 @@ static inline int handle_passthrough_pagefault_32pae(struct guest_info * info, int pde_index = PDE32PAE_INDEX(fault_addr); int pte_index = PTE32PAE_INDEX(fault_addr); - struct v3_mem_region * region = v3_get_mem_region(info->vm_info, info->cpu_id, fault_addr); + struct v3_mem_region * region = v3_get_mem_region(info->vm_info, info->vcpu_id, fault_addr); if (region == NULL) { PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n", diff --git a/palacios/src/palacios/vmm_direct_paging_64.h b/palacios/src/palacios/vmm_direct_paging_64.h index c428352..217373a 100644 --- a/palacios/src/palacios/vmm_direct_paging_64.h +++ b/palacios/src/palacios/vmm_direct_paging_64.h @@ -42,7 +42,7 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * core, addr int pde_index = PDE64_INDEX(fault_addr); int pte_index = PTE64_INDEX(fault_addr); - struct v3_mem_region * region = v3_get_mem_region(core->vm_info, core->cpu_id, fault_addr); + struct v3_mem_region * region = v3_get_mem_region(core->vm_info, core->vcpu_id, fault_addr); int page_size = PAGE_SIZE_4KB; if (region == NULL) { diff --git a/palacios/src/palacios/vmm_extensions.c b/palacios/src/palacios/vmm_extensions.c index 1db9dc6..defad8f 100644 --- a/palacios/src/palacios/vmm_extensions.c +++ b/palacios/src/palacios/vmm_extensions.c @@ -144,7 +144,7 @@ int v3_init_core_extensions(struct guest_info * core) { if ((ext->impl) && (ext->impl->core_init)) { if (ext->impl->core_init(core, ext->priv_data) == -1) { PrintError("Error configuring per core extension %s on core %d\n", - ext->impl->name, core->cpu_id); + ext->impl->name, core->vcpu_id); return -1; } } diff --git a/palacios/src/palacios/vmm_mem.c b/palacios/src/palacios/vmm_mem.c index cb5993a..6bb9f5a 100644 --- a/palacios/src/palacios/vmm_mem.c +++ b/palacios/src/palacios/vmm_mem.c @@ -478,7 +478,7 @@ uint32_t v3_get_max_page_size(struct guest_info * core, addr_t page_addr, v3_cpu pg_start = PAGE_ADDR_4MB(page_addr); pg_end = (pg_start + PAGE_SIZE_4MB); - reg = get_overlapping_region(core->vm_info, core->cpu_id, pg_start, pg_end); + reg = get_overlapping_region(core->vm_info, core->vcpu_id, pg_start, pg_end); if ((reg) && ((reg->host_addr % PAGE_SIZE_4MB) == 0)) { page_size = PAGE_SIZE_4MB; @@ -490,7 +490,7 @@ uint32_t v3_get_max_page_size(struct guest_info * core, addr_t page_addr, v3_cpu pg_start = PAGE_ADDR_2MB(page_addr); pg_end = (pg_start + PAGE_SIZE_2MB); - reg = get_overlapping_region(core->vm_info, core->cpu_id, pg_start, pg_end); + reg = get_overlapping_region(core->vm_info, core->vcpu_id, pg_start, pg_end); if ((reg) && ((reg->host_addr % PAGE_SIZE_2MB) == 0)) { page_size = PAGE_SIZE_2MB; @@ -504,7 +504,7 @@ uint32_t v3_get_max_page_size(struct guest_info * core, addr_t page_addr, v3_cpu pg_start = PAGE_ADDR_1GB(page_addr); pg_end = (pg_start + PAGE_SIZE_1GB); - reg = get_overlapping_region(core->vm_info, core->cpu_id, pg_start, pg_end); + reg = get_overlapping_region(core->vm_info, core->vcpu_id, pg_start, pg_end); if ((reg) && ((reg->host_addr % PAGE_SIZE_1GB) == 0)) { page_size = PAGE_SIZE_1GB; @@ -516,7 +516,7 @@ uint32_t v3_get_max_page_size(struct guest_info * core, addr_t page_addr, v3_cpu pg_start = PAGE_ADDR_2MB(page_addr); pg_end = (pg_start + PAGE_SIZE_2MB); - reg = get_overlapping_region(core->vm_info, core->cpu_id, pg_start, pg_end); + reg = get_overlapping_region(core->vm_info, core->vcpu_id, pg_start, pg_end); if ((reg) && ((reg->host_addr % PAGE_SIZE_2MB) == 0)) { page_size = PAGE_SIZE_2MB; diff --git a/palacios/src/palacios/vmm_mem_hook.c b/palacios/src/palacios/vmm_mem_hook.c index aee8c33..ee632b0 100644 --- a/palacios/src/palacios/vmm_mem_hook.c +++ b/palacios/src/palacios/vmm_mem_hook.c @@ -169,7 +169,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue src_reg = reg; } else { // Note that this should only trigger for string operations - src_reg = v3_get_mem_region(core->vm_info, core->cpu_id, src_mem_op_gpa); + src_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, src_mem_op_gpa); } if (src_reg == NULL) { @@ -182,7 +182,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue // We don't check whether the region is a hook here because it doesn't yet matter. // These hva calculations will be true regardless if (src_reg->flags.alloced == 0) { - src_mem_op_hva = (addr_t)(hooks->hook_hvas_1 + (PAGE_SIZE * core->cpu_id)); + src_mem_op_hva = (addr_t)(hooks->hook_hvas_1 + (PAGE_SIZE * core->vcpu_id)); } else { // We already have the region so we can do the conversion ourselves src_mem_op_hva = (addr_t)V3_VAddr((void *)((src_mem_op_gpa - src_reg->guest_start) + src_reg->host_addr)); @@ -215,7 +215,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue dst_reg = reg; } else { // Note that this should only trigger for string operations - dst_reg = v3_get_mem_region(core->vm_info, core->cpu_id, dst_mem_op_gpa); + dst_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, dst_mem_op_gpa); } if (dst_reg == NULL) { @@ -228,7 +228,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue // We don't check whether the region is a hook here because it doesn't yet matter. // These hva calculations will be true regardless if (dst_reg->flags.alloced == 0) { - dst_mem_op_hva = (addr_t)(hooks->hook_hvas_2 + (PAGE_SIZE * core->cpu_id)); + dst_mem_op_hva = (addr_t)(hooks->hook_hvas_2 + (PAGE_SIZE * core->vcpu_id)); } else { // We already have the region so we can do the conversion ourselves dst_mem_op_hva = (addr_t)V3_VAddr((void *)((dst_mem_op_gpa - dst_reg->guest_start) + dst_reg->host_addr)); diff --git a/palacios/src/palacios/vmm_symspy.c b/palacios/src/palacios/vmm_symspy.c index 7c17c01..caf1a8c 100644 --- a/palacios/src/palacios/vmm_symspy.c +++ b/palacios/src/palacios/vmm_symspy.c @@ -56,7 +56,7 @@ static int symspy_msr_write(struct guest_info * core, uint_t msr, struct v3_msr if (global_state->active == 1) { // unmap page - struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->cpu_id, + struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, (addr_t)global_state->global_guest_pa); if (old_reg == NULL) { @@ -84,7 +84,7 @@ static int symspy_msr_write(struct guest_info * core, uint_t msr, struct v3_msr if (local_state->active == 1) { // unmap page - struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->cpu_id, + struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, (addr_t)local_state->local_guest_pa); if (old_reg == NULL) { @@ -102,7 +102,7 @@ static int symspy_msr_write(struct guest_info * core, uint_t msr, struct v3_msr local_state->active = 1; // map page - v3_add_shadow_mem(core->vm_info, core->cpu_id, (addr_t)local_state->local_guest_pa, + v3_add_shadow_mem(core->vm_info, core->vcpu_id, (addr_t)local_state->local_guest_pa, (addr_t)(local_state->local_guest_pa + PAGE_SIZE_4KB - 1), local_state->local_page_pa); } else { @@ -136,7 +136,7 @@ int v3_init_symspy_core(struct guest_info * core, struct v3_symspy_local_state * state->local_page = (struct v3_symspy_local_page *)V3_VAddr((void *)state->local_page_pa); memset(state->local_page, 0, PAGE_SIZE_4KB); - snprintf((uint8_t *)&(state->local_page->magic), 8, "V3V.%d", core->cpu_id); + snprintf((uint8_t *)&(state->local_page->magic), 8, "V3V.%d", core->vcpu_id); return 0; } diff --git a/palacios/src/palacios/vmm_telemetry.c b/palacios/src/palacios/vmm_telemetry.c index 09e74b8..42e7822 100644 --- a/palacios/src/palacios/vmm_telemetry.c +++ b/palacios/src/palacios/vmm_telemetry.c @@ -252,7 +252,7 @@ void v3_print_telemetry(struct v3_vm_info * vm) { struct exit_event * evt = NULL; struct rb_node * node = v3_rb_first(&(core->core_telem.exit_root)); - V3_Print("Exit information for Core %d\n", core->cpu_id); + V3_Print("Exit information for Core %d\n", core->vcpu_id); if (!node) { V3_Print("No information yet for this core\n"); diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index a0047af..fc2e37e 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -399,8 +399,8 @@ void v3_init_time_core(struct guest_info * info) { if (khz) { time_state->guest_cpu_freq = atoi(khz); - PrintDebug("Core %d CPU frequency requested at %d khz.\n", - info->cpu_id, time_state->guest_cpu_freq); + PrintDebug("Logical Core %d (vcpu=%d) CPU frequency requested at %d khz.\n", + info->pcpu_id, info->vcpu_id, time_state->guest_cpu_freq); } if ( (khz == NULL) || @@ -410,8 +410,8 @@ void v3_init_time_core(struct guest_info * info) { time_state->guest_cpu_freq = time_state->host_cpu_freq; } - PrintDebug("Core %d CPU frequency set to %d KHz (host CPU frequency = %d KHz).\n", - info->cpu_id, + PrintDebug("Logical Core %d (vcpu=%d) CPU frequency set to %d KHz (host CPU frequency = %d KHz).\n", + info->pcpu_id, info->vcpu_id, time_state->guest_cpu_freq, time_state->host_cpu_freq); diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 4a7a6e9..123e23b 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -264,7 +264,7 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) v3_vmxassist_init(core, vmx_state); } else if ((core->shdw_pg_mode == NESTED_PAGING) && - (v3_cpu_types[core->cpu_id] == V3_VMX_EPT_CPU)) { + (v3_cpu_types[core->pcpu_id] == V3_VMX_EPT_CPU)) { #define CR0_PE 0x00000001 #define CR0_PG 0x80000000 @@ -297,7 +297,7 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) } } else if ((core->shdw_pg_mode == NESTED_PAGING) && - (v3_cpu_types[core->cpu_id] == V3_VMX_EPT_UG_CPU)) { + (v3_cpu_types[core->pcpu_id] == V3_VMX_EPT_UG_CPU)) { int i = 0; // For now we will assume that unrestricted guest mode is assured w/ EPT @@ -879,30 +879,30 @@ int v3_vmx_enter(struct guest_info * info) { int v3_start_vmx_guest(struct guest_info * info) { - PrintDebug("Starting VMX core %u\n", info->cpu_id); + PrintDebug("Starting VMX core %u\n", info->vcpu_id); - if (info->cpu_id == 0) { + if (info->vcpu_id == 0) { info->core_run_state = CORE_RUNNING; info->vm_info->run_state = VM_RUNNING; } else { - PrintDebug("VMX core %u: Waiting for core initialization\n", info->cpu_id); + PrintDebug("VMX core %u: Waiting for core initialization\n", info->vcpu_id); while (info->core_run_state == CORE_STOPPED) { v3_yield(info); - //PrintDebug("VMX core %u: still waiting for INIT\n",info->cpu_id); + //PrintDebug("VMX core %u: still waiting for INIT\n",info->vcpu_id); } - PrintDebug("VMX core %u initialized\n", info->cpu_id); + PrintDebug("VMX core %u initialized\n", info->vcpu_id); } PrintDebug("VMX core %u: I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n", - info->cpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base), + info->vcpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base), info->segments.cs.limit, (void *)(info->rip)); - PrintDebug("VMX core %u: Launching VMX VM\n", info->cpu_id); + PrintDebug("VMX core %u: Launching VMX VM on logical core %u\n", info->vcpu_id, info->pcpu_id); v3_start_time(info); @@ -992,7 +992,7 @@ void v3_init_vmx_cpu(int cpu_id) { PrintDebug("VMXON pointer: 0x%p\n", (void *)host_vmcs_ptrs[cpu_id]); if (vmx_on(host_vmcs_ptrs[cpu_id]) == VMX_SUCCESS) { - PrintDebug("VMX Enabled\n"); + V3_Print("VMX Enabled\n"); } else { PrintError("VMX initialization failure\n"); return; diff --git a/palacios/src/palacios/vmx_ept.c b/palacios/src/palacios/vmx_ept.c index bf1ab86..a66ad6b 100644 --- a/palacios/src/palacios/vmx_ept.c +++ b/palacios/src/palacios/vmx_ept.c @@ -77,7 +77,7 @@ int v3_handle_ept_fault(struct guest_info * core, addr_t fault_addr, struct ept_ int pde_index = PDE64_INDEX(fault_addr); int pte_index = PTE64_INDEX(fault_addr); - struct v3_mem_region * region = v3_get_mem_region(core->vm_info, core->cpu_id, fault_addr); + struct v3_mem_region * region = v3_get_mem_region(core->vm_info, core->vcpu_id, fault_addr); int page_size = PAGE_SIZE_4KB;