aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/kvm/state_test.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2018-07-29 00:14:11 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2018-08-06 17:58:44 +0200
commit9a78bdf31da79a2a58585474598afcf44b14b245 (patch)
tree02c165b491b7c0b4a0a0027b18773e8a0fa9f161 /tools/testing/selftests/kvm/state_test.c
parentKVM: nVMX: include shadow vmcs12 in nested state (diff)
downloadlinux-dev-9a78bdf31da79a2a58585474598afcf44b14b245.tar.xz
linux-dev-9a78bdf31da79a2a58585474598afcf44b14b245.zip
KVM: selftests: add tests for shadow VMCS save/restore
This includes setting up the shadow VMCS and the secondary execution controls in lib/vmx.c. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to '')
-rw-r--r--tools/testing/selftests/kvm/state_test.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/tools/testing/selftests/kvm/state_test.c b/tools/testing/selftests/kvm/state_test.c
index 8554a34f826e..ecabf25b7077 100644
--- a/tools/testing/selftests/kvm/state_test.c
+++ b/tools/testing/selftests/kvm/state_test.c
@@ -53,7 +53,15 @@ void l2_guest_code(void)
/* Exit to L1 */
vmcall();
- GUEST_SYNC(7);
+ /* L1 has now set up a shadow VMCS for us. */
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+ GUEST_SYNC(9);
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+ GUEST_ASSERT(!vmwrite(GUEST_RIP, 0xc0fffee));
+ GUEST_SYNC(10);
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0fffee);
+ GUEST_ASSERT(!vmwrite(GUEST_RIP, 0xc0ffffee));
+ GUEST_SYNC(11);
/* Done, exit to L1 and never come back. */
vmcall();
@@ -94,9 +102,31 @@ void l1_guest_code(struct vmx_pages *vmx_pages)
vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + 3);
+ vmwrite(SECONDARY_VM_EXEC_CONTROL, SECONDARY_EXEC_SHADOW_VMCS);
+ vmwrite(VMCS_LINK_POINTER, vmx_pages->shadow_vmcs_gpa);
+
+ GUEST_ASSERT(!vmptrld(vmx_pages->shadow_vmcs_gpa));
+ GUEST_ASSERT(vmlaunch());
+ GUEST_SYNC(7);
+ GUEST_ASSERT(vmlaunch());
+ GUEST_ASSERT(vmresume());
+
+ vmwrite(GUEST_RIP, 0xc0ffee);
+ GUEST_SYNC(8);
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffee);
+
+ GUEST_ASSERT(!vmptrld(vmx_pages->vmcs_gpa));
GUEST_ASSERT(!vmresume());
GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
- GUEST_SYNC(8);
+
+ GUEST_ASSERT(!vmptrld(vmx_pages->shadow_vmcs_gpa));
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
+ GUEST_ASSERT(vmlaunch());
+ GUEST_ASSERT(vmresume());
+ GUEST_SYNC(12);
+ GUEST_ASSERT(vmreadz(GUEST_RIP) == 0xc0ffffee);
+ GUEST_ASSERT(vmlaunch());
+ GUEST_ASSERT(vmresume());
}
void guest_code(struct vmx_pages *vmx_pages)