KVM: Be more careful restoring fs on lightweight vmexit
i386 wants fs for accessing the pda even on a lightweight exit, so ensure we can always restore it. This fixes a regression on i386 introduced by the lightweight vmexit patch. Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
a25f7e1f8c
commit
621358455a
1 changed files with 11 additions and 11 deletions
|
@ -1832,16 +1832,21 @@ preempted:
|
||||||
* Set host fs and gs selectors. Unfortunately, 22.2.3 does not
|
* Set host fs and gs selectors. Unfortunately, 22.2.3 does not
|
||||||
* allow segment selectors with cpl > 0 or ti == 1.
|
* allow segment selectors with cpl > 0 or ti == 1.
|
||||||
*/
|
*/
|
||||||
fs_sel = read_fs();
|
|
||||||
gs_sel = read_gs();
|
|
||||||
ldt_sel = read_ldt();
|
ldt_sel = read_ldt();
|
||||||
fs_gs_ldt_reload_needed = (fs_sel & 7) | (gs_sel & 7) | ldt_sel;
|
fs_gs_ldt_reload_needed = ldt_sel;
|
||||||
if (!fs_gs_ldt_reload_needed) {
|
fs_sel = read_fs();
|
||||||
|
if (!(fs_sel & 7))
|
||||||
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
|
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
|
||||||
vmcs_write16(HOST_GS_SELECTOR, gs_sel);
|
else {
|
||||||
} else {
|
|
||||||
vmcs_write16(HOST_FS_SELECTOR, 0);
|
vmcs_write16(HOST_FS_SELECTOR, 0);
|
||||||
|
fs_gs_ldt_reload_needed = 1;
|
||||||
|
}
|
||||||
|
gs_sel = read_gs();
|
||||||
|
if (!(gs_sel & 7))
|
||||||
|
vmcs_write16(HOST_GS_SELECTOR, gs_sel);
|
||||||
|
else {
|
||||||
vmcs_write16(HOST_GS_SELECTOR, 0);
|
vmcs_write16(HOST_GS_SELECTOR, 0);
|
||||||
|
fs_gs_ldt_reload_needed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
@ -2035,11 +2040,6 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/*
|
|
||||||
* Reload segment selectors ASAP. (it's needed for a functional
|
|
||||||
* kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64
|
|
||||||
* relies on having 0 in %gs for the CPU PDA to work.)
|
|
||||||
*/
|
|
||||||
if (fs_gs_ldt_reload_needed) {
|
if (fs_gs_ldt_reload_needed) {
|
||||||
load_ldt(ldt_sel);
|
load_ldt(ldt_sel);
|
||||||
load_fs(fs_sel);
|
load_fs(fs_sel);
|
||||||
|
|
Loading…
Reference in a new issue