diff options
author | Avi Kivity <avi@qumranet.com> | 2007-05-01 04:32:28 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:38 -0400 |
commit | 621358455ae043ab39bc3481f13b101bd6016c8d (patch) | |
tree | 6266ec89f457c039d94add676f1d798381efae2a /drivers/kvm/vmx.c | |
parent | a25f7e1f8c1ff68213a63dada9d5e32dc1a0f587 (diff) |
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>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r-- | drivers/kvm/vmx.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 9ebb18d07bde..49cadd31120b 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -1832,16 +1832,21 @@ preempted: | |||
1832 | * Set host fs and gs selectors. Unfortunately, 22.2.3 does not | 1832 | * Set host fs and gs selectors. Unfortunately, 22.2.3 does not |
1833 | * allow segment selectors with cpl > 0 or ti == 1. | 1833 | * allow segment selectors with cpl > 0 or ti == 1. |
1834 | */ | 1834 | */ |
1835 | fs_sel = read_fs(); | ||
1836 | gs_sel = read_gs(); | ||
1837 | ldt_sel = read_ldt(); | 1835 | ldt_sel = read_ldt(); |
1838 | fs_gs_ldt_reload_needed = (fs_sel & 7) | (gs_sel & 7) | ldt_sel; | 1836 | fs_gs_ldt_reload_needed = ldt_sel; |
1839 | if (!fs_gs_ldt_reload_needed) { | 1837 | fs_sel = read_fs(); |
1838 | if (!(fs_sel & 7)) | ||
1840 | vmcs_write16(HOST_FS_SELECTOR, fs_sel); | 1839 | vmcs_write16(HOST_FS_SELECTOR, fs_sel); |
1841 | vmcs_write16(HOST_GS_SELECTOR, gs_sel); | 1840 | else { |
1842 | } else { | ||
1843 | vmcs_write16(HOST_FS_SELECTOR, 0); | 1841 | vmcs_write16(HOST_FS_SELECTOR, 0); |
1842 | fs_gs_ldt_reload_needed = 1; | ||
1843 | } | ||
1844 | gs_sel = read_gs(); | ||
1845 | if (!(gs_sel & 7)) | ||
1846 | vmcs_write16(HOST_GS_SELECTOR, gs_sel); | ||
1847 | else { | ||
1844 | vmcs_write16(HOST_GS_SELECTOR, 0); | 1848 | vmcs_write16(HOST_GS_SELECTOR, 0); |
1849 | fs_gs_ldt_reload_needed = 1; | ||
1845 | } | 1850 | } |
1846 | 1851 | ||
1847 | #ifdef CONFIG_X86_64 | 1852 | #ifdef CONFIG_X86_64 |
@@ -2035,11 +2040,6 @@ again: | |||
2035 | } | 2040 | } |
2036 | 2041 | ||
2037 | out: | 2042 | out: |
2038 | /* | ||
2039 | * Reload segment selectors ASAP. (it's needed for a functional | ||
2040 | * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64 | ||
2041 | * relies on having 0 in %gs for the CPU PDA to work.) | ||
2042 | */ | ||
2043 | if (fs_gs_ldt_reload_needed) { | 2043 | if (fs_gs_ldt_reload_needed) { |
2044 | load_ldt(ldt_sel); | 2044 | load_ldt(ldt_sel); |
2045 | load_fs(fs_sel); | 2045 | load_fs(fs_sel); |