summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-05-01 11:32:28 +0300
committerAvi Kivity <avi@qumranet.com>2007-07-16 12:05:38 +0300
commit621358455ae043ab39bc3481f13b101bd6016c8d (patch)
tree6266ec89f457c039d94add676f1d798381efae2a
parenta25f7e1f8c1ff68213a63dada9d5e32dc1a0f587 (diff)
downloadkernel-crypto-621358455ae043ab39bc3481f13b101bd6016c8d.tar.gz
kernel-crypto-621358455ae043ab39bc3481f13b101bd6016c8d.tar.xz
kernel-crypto-621358455ae043ab39bc3481f13b101bd6016c8d.zip
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>
-rw-r--r--drivers/kvm/vmx.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 9ebb18d07bd..49cadd31120 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1832,16 +1832,21 @@ preempted:
* Set host fs and gs selectors. Unfortunately, 22.2.3 does not
* allow segment selectors with cpl > 0 or ti == 1.
*/
- fs_sel = read_fs();
- gs_sel = read_gs();
ldt_sel = read_ldt();
- fs_gs_ldt_reload_needed = (fs_sel & 7) | (gs_sel & 7) | ldt_sel;
- if (!fs_gs_ldt_reload_needed) {
+ fs_gs_ldt_reload_needed = ldt_sel;
+ fs_sel = read_fs();
+ if (!(fs_sel & 7))
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
- vmcs_write16(HOST_GS_SELECTOR, gs_sel);
- } else {
+ else {
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);
+ fs_gs_ldt_reload_needed = 1;
}
#ifdef CONFIG_X86_64
@@ -2035,11 +2040,6 @@ again:
}
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) {
load_ldt(ldt_sel);
load_fs(fs_sel);