diff options
author | Bryan Cantrill <bryan@joyent.com> | 2011-08-01 15:44:59 -0700 |
---|---|---|
committer | Bryan Cantrill <bryan@joyent.com> | 2011-08-01 15:44:59 -0700 |
commit | 034dc85e563a1c15ef8eef125c11de9dd7918ae9 (patch) | |
tree | 243833992d032527fb4816c400197990f1763c20 /kvm_vmx.c | |
parent | 1c0b3b8f7bfb63054f9681143bf58ec3e3e77ecd (diff) | |
download | illumos-kvm-034dc85e563a1c15ef8eef125c11de9dd7918ae9.tar.gz |
HVM-540 enabling kvm-vmx-vmread probe induces double fault
Diffstat (limited to 'kvm_vmx.c')
-rw-r--r-- | kvm_vmx.c | 18 |
1 files changed, 15 insertions, 3 deletions
@@ -786,14 +786,26 @@ __vmx_load_host_state(struct vcpu_vmx *vmx) if (vmx->host_state.fs_reload_needed) kvm_load_fs(vmx->host_state.fs_sel); if (vmx->host_state.gs_ldt_reload_needed) { + unsigned long gsbase; + kvm_load_ldt(vmx->host_state.ldt_sel); /* - * If we have to reload gs, we must take care to - * preserve our gs base. + * If we have to reload GS, we must take care to preserve our + * GSBASE. Note that between the kvm_load_gs() and the + * completion of writing the MSR, GS is essentially in a + * corrupt state -- we cannot allow code to be revectored + * in this window. In particular, this means that we not + * hit a DTrace probe in this window (which will need the + * intact GS to get to the CPU pointer). Both kvm_load_gs() + * and wrmsrl() turn into inlines or non-instrumentable + * leaf routines, but vmcs_readl() has an SDT probe -- so we + * call vmcs_readl() to get the HOST_GS_BASE before the call + * to kvm_load_gs(). */ cli(); + gsbase = vmcs_readl(HOST_GS_BASE); kvm_load_gs(vmx->host_state.gs_sel); - wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); + wrmsrl(MSR_GS_BASE, gsbase); sti(); } reload_tss(); |