struct guest_pcore *load_guest_pcore(struct proc *p, int guest_pcoreid, bool *should_vmresume) { struct guest_pcore *gpc; struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; gpc = lookup_guest_pcore(p, guest_pcoreid); if (!gpc) return 0; assert(pcpui->guest_pcoreid == -1); spin_lock(&p->vmm.lock); if (gpc->cpu != -1) { spin_unlock(&p->vmm.lock); return 0; } gpc->cpu = core_id(); spin_unlock(&p->vmm.lock); /* We've got dibs on the gpc; we don't need to hold the lock any longer. */ pcpui->guest_pcoreid = guest_pcoreid; vmx_load_guest_pcore(gpc, should_vmresume); /* Load guest's xcr0 */ lxcr0(gpc->xcr0); /* Manual MSR save/restore */ write_kern_gsbase(gpc->msr_kern_gs_base); if (gpc->msr_star != AKAROS_MSR_STAR) write_msr(MSR_STAR, gpc->msr_star); if (gpc->msr_lstar != AKAROS_MSR_LSTAR) write_msr(MSR_LSTAR, gpc->msr_lstar); if (gpc->msr_sfmask != AKAROS_MSR_SFMASK) write_msr(MSR_SFMASK, gpc->msr_sfmask); return gpc; }
struct guest_pcore *load_guest_pcore(struct proc *p, int guest_pcoreid) { struct guest_pcore *gpc; struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; gpc = lookup_guest_pcore(p, guest_pcoreid); if (!gpc) return 0; assert(pcpui->guest_pcoreid == -1); spin_lock(&p->vmm.lock); if (gpc->cpu != -1) { spin_unlock(&p->vmm.lock); return 0; } gpc->cpu = core_id(); spin_unlock(&p->vmm.lock); /* We've got dibs on the gpc; we don't need to hold the lock any longer. */ pcpui->guest_pcoreid = guest_pcoreid; ept_sync_context(gpc_get_eptp(gpc)); vmx_load_guest_pcore(gpc); /* Load guest's xcr0 */ lxcr0(gpc->xcr0); return gpc; }