KVM: vmx: refactor segmentation code in vmx_save_host_state()
Use local variables in vmx_save_host_state() to temporarily track the selector and base values for FS and GS, and reorganize the code so that the 64-bit vs 32-bit portions are contained within a single #ifdef. This refactoring paves the way for future patches to modify the updating of VMCS state with minimal changes to the code, and (hopefully) simplifies resolving a likely conflict with another in-flight patch[1] by being the whipping boy for future patches. [1] https://www.spinics.net/lists/kvm/msg171647.html Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
e49fcb8b9e
commit
e368b875a8
@ -2662,8 +2662,9 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
|||||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
int cpu = raw_smp_processor_id();
|
int cpu = raw_smp_processor_id();
|
||||||
unsigned long fs_base, kernel_gs_base;
|
|
||||||
#endif
|
#endif
|
||||||
|
unsigned long fs_base, gs_base;
|
||||||
|
u16 fs_sel, gs_sel;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (vmx->host_state.loaded)
|
if (vmx->host_state.loaded)
|
||||||
@ -2678,49 +2679,51 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
|||||||
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
|
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
savesegment(ds, vmx->host_state.ds_sel);
|
||||||
|
savesegment(es, vmx->host_state.es_sel);
|
||||||
|
|
||||||
|
gs_base = cpu_kernelmode_gs_base(cpu);
|
||||||
if (likely(is_64bit_mm(current->mm))) {
|
if (likely(is_64bit_mm(current->mm))) {
|
||||||
save_fsgs_for_kvm();
|
save_fsgs_for_kvm();
|
||||||
vmx->host_state.fs_sel = current->thread.fsindex;
|
fs_sel = current->thread.fsindex;
|
||||||
vmx->host_state.gs_sel = current->thread.gsindex;
|
gs_sel = current->thread.gsindex;
|
||||||
fs_base = current->thread.fsbase;
|
fs_base = current->thread.fsbase;
|
||||||
kernel_gs_base = current->thread.gsbase;
|
vmx->msr_host_kernel_gs_base = current->thread.gsbase;
|
||||||
} else {
|
} else {
|
||||||
#endif
|
savesegment(fs, fs_sel);
|
||||||
savesegment(fs, vmx->host_state.fs_sel);
|
savesegment(gs, gs_sel);
|
||||||
savesegment(gs, vmx->host_state.gs_sel);
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
fs_base = read_msr(MSR_FS_BASE);
|
fs_base = read_msr(MSR_FS_BASE);
|
||||||
kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
|
vmx->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_long_mode(&vmx->vcpu))
|
||||||
|
wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
|
||||||
|
#else
|
||||||
|
savesegment(fs, fs_sel);
|
||||||
|
savesegment(gs, gs_sel);
|
||||||
|
fs_base = segment_base(fs_sel);
|
||||||
|
gs_base = segment_base(gs_sel);
|
||||||
#endif
|
#endif
|
||||||
if (!(vmx->host_state.fs_sel & 7)) {
|
|
||||||
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
|
vmx->host_state.fs_sel = fs_sel;
|
||||||
|
if (!(fs_sel & 7)) {
|
||||||
|
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
|
||||||
vmx->host_state.fs_reload_needed = 0;
|
vmx->host_state.fs_reload_needed = 0;
|
||||||
} else {
|
} else {
|
||||||
vmcs_write16(HOST_FS_SELECTOR, 0);
|
vmcs_write16(HOST_FS_SELECTOR, 0);
|
||||||
vmx->host_state.fs_reload_needed = 1;
|
vmx->host_state.fs_reload_needed = 1;
|
||||||
}
|
}
|
||||||
if (!(vmx->host_state.gs_sel & 7))
|
vmx->host_state.gs_sel = gs_sel;
|
||||||
vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
|
if (!(gs_sel & 7))
|
||||||
|
vmcs_write16(HOST_GS_SELECTOR, gs_sel);
|
||||||
else {
|
else {
|
||||||
vmcs_write16(HOST_GS_SELECTOR, 0);
|
vmcs_write16(HOST_GS_SELECTOR, 0);
|
||||||
vmx->host_state.gs_ldt_reload_needed = 1;
|
vmx->host_state.gs_ldt_reload_needed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
savesegment(ds, vmx->host_state.ds_sel);
|
|
||||||
savesegment(es, vmx->host_state.es_sel);
|
|
||||||
|
|
||||||
vmcs_writel(HOST_FS_BASE, fs_base);
|
vmcs_writel(HOST_FS_BASE, fs_base);
|
||||||
vmcs_writel(HOST_GS_BASE, cpu_kernelmode_gs_base(cpu));
|
vmcs_writel(HOST_GS_BASE, gs_base);
|
||||||
|
|
||||||
vmx->msr_host_kernel_gs_base = kernel_gs_base;
|
|
||||||
if (is_long_mode(&vmx->vcpu))
|
|
||||||
wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
|
|
||||||
#else
|
|
||||||
vmcs_writel(HOST_FS_BASE, segment_base(vmx->host_state.fs_sel));
|
|
||||||
vmcs_writel(HOST_GS_BASE, segment_base(vmx->host_state.gs_sel));
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < vmx->save_nmsrs; ++i)
|
for (i = 0; i < vmx->save_nmsrs; ++i)
|
||||||
kvm_set_shared_msr(vmx->guest_msrs[i].index,
|
kvm_set_shared_msr(vmx->guest_msrs[i].index,
|
||||||
vmx->guest_msrs[i].data,
|
vmx->guest_msrs[i].data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user