Patch "kvm: x86: fix RSM when PCID is non-zero" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
kvm: x86: fix RSM when PCID is non-zero
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-x86-fix-rsm-when-pcid-is-non-zero.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
fae1a3e775cca8c3a9e0eb34443b310871a15a92Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <[email protected]>
Date: Thu, 21 Dec 2017 00:49:14 +0100
Subject: kvm: x86: fix RSM when PCID is non-zero
From: Paolo Bonzini <[email protected]>
commit fae1a3e775cca8c3a9e0eb34443b310871a15a92 upstream.
rsm_load_state_64() and rsm_enter_protected_mode() load CR3, then CR4 & ~PCIDE, then CR0, then CR4.
However, setting CR4.PCIDE fails if CR3[11:0] != 0. It's probably easier in the long run to replace rsm_enter_protected_mode() with an emulator callback that sets all the special registers (like KVM_SET_SREGS would do). For now, set the PCID field of CR3 only after CR4.PCIDE is 1.
--- arch/x86/kvm/emulate.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-)
arch/x86/kvm/emulate.c +25 -7
@@ -2383,9 +2383,21 @@ static int rsm_load_seg_64(struct x86_em }static int rsm_enter_protected_mode (struct x86_emulate_ctxt *ctxt, -u64 cr0,u64 cr4) +u64 cr0,u64 cr3,u64 cr4) {int bad; +u64 pcid; + +/* In order to later set CR4.PCIDE, CR3[11:0] must be zero. */ + pcid =0 ; +if (cr4 &X86_CR4_PCIDE ) { + pcid = cr3 &0xfff ; + cr3 &= ~0xfff ; + } + + bad = ctxt->ops->set_cr (ctxt,3 , cr3); +if (bad) +return X86EMUL_UNHANDLEABLE ;/* * First enable PAE, long mode needs it before CR0.PG = 1 is set.
@@ -2404,6 +2416,12 @@ static int rsm_enter_protected_mode(stru bad = ctxt->ops->set_cr (ctxt,4 , cr4);if (bad)return X86EMUL_UNHANDLEABLE ; +if (pcid) { + bad = ctxt->ops->set_cr (ctxt,3 , cr3 | pcid); +if (bad) +return X86EMUL_UNHANDLEABLE ; + } + }return X86EMUL_CONTINUE ;
@@ -2414,11 +2432,11 @@ static int rsm_load_state_32(struct x86_struct desc_struct desc;struct desc_ptr dt;u16 selector; -u32 val, cr0, cr4; +u32 val, cr0, cr3, cr4;int i; cr0 =GET_SMSTATE (u32, smbase,0x7ffc ); - ctxt->ops->set_cr (ctxt,3 ,GET_SMSTATE (u32, smbase,0x7ff8 )); + cr3 =GET_SMSTATE (u32, smbase,0x7ff8 ); ctxt->eflags =GET_SMSTATE (u32, smbase,0x7ff4 ) |X86_EFLAGS_FIXED ; ctxt->_eip =GET_SMSTATE (u32, smbase,0x7ff0 );
@@ -2460,14 +2478,14 @@ static int rsm_load_state_32(struct x86_ ctxt->ops->set_smbase (ctxt,GET_SMSTATE (u32, smbase,0x7ef8 )); -return rsm_enter_protected_mode (ctxt, cr0, cr4); +return rsm_enter_protected_mode (ctxt, cr0, cr3, cr4); }static int rsm_load_state_64 (struct x86_emulate_ctxt *ctxt,u64 smbase) {struct desc_struct desc;struct desc_ptr dt; -u64 val, cr0, cr4; +u64 val, cr0, cr3, cr4;u32 base3;u16 selector;int i, r;
@@ -2484,7 +2502,7 @@ static int rsm_load_state_64(struct x86_ ctxt->ops->set_dr (ctxt,7 , (val &DR7_VOLATILE ) |DR7_FIXED_1 ); cr0 =GET_SMSTATE (u64, smbase,0x7f58 ); - ctxt->ops->set_cr (ctxt,3 ,GET_SMSTATE (u64, smbase,0x7f50 )); + cr3 =GET_SMSTATE (u64, smbase,0x7f50 ); cr4 =GET_SMSTATE (u64, smbase,0x7f48 ); ctxt->ops->set_smbase (ctxt,GET_SMSTATE (u32, smbase,0x7f00 )); val =GET_SMSTATE (u64, smbase,0x7ed0 );
@@ -2512,7 +2530,7 @@ static int rsm_load_state_64(struct x86_ dt.address =GET_SMSTATE (u64, smbase,0x7e68 ); ctxt->ops->set_gdt (ctxt, &dt); - r =rsm_enter_protected_mode (ctxt, cr0, cr4); + r =rsm_enter_protected_mode (ctxt, cr0, cr3, cr4);if (r !=X86EMUL_CONTINUE )return r;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/kvm-x86-fix-load-rflags-w-o-the-fixed-bit.patch queue-4.4/kvm-x86-fix-rsm-when-pcid-is-non-zero.patch