svn commit: r271086 - projects/bhyve_svm/sys/amd64/vmm/amd
Neel Natu
neel at FreeBSD.org
Thu Sep 4 06:00:19 UTC 2014
Author: neel
Date: Thu Sep 4 06:00:18 2014
New Revision: 271086
URL: http://svnweb.freebsd.org/changeset/base/271086
Log:
Consolidate the code to restore the host TSS after a #VMEXIT into a single
function restore_host_tss().
Don't bother to restore MSR_KGSBASE after a #VMEXIT since it is not used in
the kernel. It will be restored on return to userspace.
Discussed with: Anish Gupta (akgupt3 at gmail.com)
Modified:
projects/bhyve_svm/sys/amd64/vmm/amd/svm.c
Modified: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c
==============================================================================
--- projects/bhyve_svm/sys/amd64/vmm/amd/svm.c Thu Sep 4 03:31:48 2014 (r271085)
+++ projects/bhyve_svm/sys/amd64/vmm/amd/svm.c Thu Sep 4 06:00:18 2014 (r271086)
@@ -1104,22 +1104,21 @@ svm_inj_interrupts(struct svm_softc *svm
VCPU_CTR1(svm_sc->vm, vcpu, "SVM:event injected,vector=%d.\n", vector);
}
-/*
- * Restore host Task Register selector type after every vcpu exit.
- */
static void
-setup_tss_type(void)
+restore_host_tss(void)
{
- struct system_segment_descriptor *desc;
+ struct system_segment_descriptor *tss_sd;
- desc = (struct system_segment_descriptor *)&gdt[curcpu * NGDT +
- GPROC0_SEL];
/*
- * Task selector that should be restored in host is
- * 64-bit available(9), not what is read(0xb), see
- * APMvol2 Rev3.21 4.8.3 System Descriptors table.
+ * The TSS descriptor was in use prior to launching the guest so it
+ * has been marked busy.
+ *
+ * 'ltr' requires the descriptor to be marked available so change the
+ * type to "64-bit available TSS".
*/
- desc->sd_type = 9;
+ tss_sd = PCPU_GET(tss);
+ tss_sd->sd_type = SDT_SYSTSS;
+ ltr(GSEL(GPROC0_SEL, SEL_KPL));
}
/*
@@ -1241,32 +1240,27 @@ svm_vmrun(void *arg, int vcpu, register_
svm_inj_interrupts(svm_sc, vcpu, vlapic);
- /* Change TSS type to available.*/
- setup_tss_type();
-
/* Launch Virtual Machine. */
svm_launch(vmcb_pa, gctx, hctx);
/*
- * Only GDTR and IDTR of host is saved and restore by SVM,
- * LDTR and TR need to be restored by VMM.
- * XXX: kernel doesn't use LDT, only user space.
+ * Restore MSR_GSBASE to point to the pcpu data area.
+ *
+ * Note that accesses done via PCPU_GET/PCPU_SET will work
+ * only after MSR_GSBASE is restored.
+ *
+ * Also note that we don't bother restoring MSR_KGSBASE
+ * since it is not used in the kernel and will be restored
+ * when the VMRUN ioctl returns to userspace.
*/
- ltr(GSEL(GPROC0_SEL, SEL_KPL));
+ wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
/*
- * Guest FS and GS selector are stashed by vmload and vmsave.
- * Host FS and GS selector are stashed by svm_launch().
- * Host GS base that holds per-cpu need to be restored before
- * enabling global interrupt.
- * FS is not used by FreeBSD kernel and kernel does restore
- * back FS selector and base of user before returning to
- * userland.
- *
- * Note: You can't use 'curcpu' which uses pcpu.
+ * The host GDTR and IDTR is saved by VMRUN and restored
+ * automatically on #VMEXIT. However, the host TSS needs
+ * to be restored explicitly.
*/
- wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
- wrmsr(MSR_KGSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
+ restore_host_tss();
/* #VMEXIT disables interrupts so re-enable them here. */
enable_gintr();
More information about the svn-src-projects
mailing list