void unload_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); assert(gpc); spin_lock(&p->vmm.lock); assert(gpc->cpu != -1); vmx_unload_guest_pcore(gpc); gpc->cpu = -1; /* Save guest's xcr0 and restore Akaros's default. */ gpc->xcr0 = rxcr0(); lxcr0(__proc_global_info.x86_default_xcr0); /* We manage these MSRs manually. */ gpc->msr_kern_gs_base = read_kern_gsbase(); gpc->msr_star = read_msr(MSR_STAR); gpc->msr_lstar = read_msr(MSR_LSTAR); gpc->msr_sfmask = read_msr(MSR_SFMASK); write_kern_gsbase((uint64_t)pcpui); if (gpc->msr_star != AKAROS_MSR_STAR) write_msr(MSR_STAR, AKAROS_MSR_STAR); if (gpc->msr_lstar != AKAROS_MSR_LSTAR) write_msr(MSR_LSTAR, AKAROS_MSR_LSTAR); if (gpc->msr_sfmask, AKAROS_MSR_SFMASK) write_msr(MSR_SFMASK, AKAROS_MSR_SFMASK); /* As soon as we unlock, this gpc can be started on another core */ spin_unlock(&p->vmm.lock); pcpui->guest_pcoreid = -1; }
void unload_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); assert(gpc); spin_lock(&p->vmm.lock); assert(gpc->cpu != -1); ept_sync_context(gpc_get_eptp(gpc)); vmx_unload_guest_pcore(gpc); gpc->cpu = -1; /* Save guest's xcr0 and restore Akaros's default. */ gpc->xcr0 = rxcr0(); lxcr0(x86_default_xcr0); /* As soon as we unlock, this gpc can be started on another core */ spin_unlock(&p->vmm.lock); pcpui->guest_pcoreid = -1; }