* [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation
@ 2020-04-13 17:24 Simon Smith
2020-04-13 23:50 ` Sean Christopherson
0 siblings, 1 reply; 4+ messages in thread
From: Simon Smith @ 2020-04-13 17:24 UTC (permalink / raw)
To: kvm; +Cc: pbonzini, Simon Smith, Jim Mattson, Peter Shier, Krish Sadhukhan
This commit adds new unit tests for commit a4d956b93904 ("KVM: nVMX:
vmread should not set rflags to specify success in case of #PF")
The two new tests force a vmread and a vmwrite on an unmapped
address to cause a #PF and verify that the low byte of %rflags is
preserved and that %rip is not advanced. The cherry-pick fixed a
bug in vmread, but we include a test for vmwrite as well for
completeness.
Before the aforementioned commit, the ALU flags would be incorrectly
cleared and %rip would be advanced (for vmread).
Reviewed-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Peter Shier <pshier@google.com>
Reviewed-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Signed-off-by: Simon Smith <brigidsmith@google.com>
---
x86/vmx.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/x86/vmx.c b/x86/vmx.c
index 647ab49408876..e9235ec4fcad9 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -32,6 +32,7 @@
#include "processor.h"
#include "alloc_page.h"
#include "vm.h"
+#include "vmalloc.h"
#include "desc.h"
#include "vmx.h"
#include "msr.h"
@@ -368,6 +369,122 @@ static void test_vmwrite_vmread(void)
free_page(vmcs);
}
+ulong finish_fault;
+u8 sentinel;
+bool handler_called;
+static void pf_handler(struct ex_regs *regs)
+{
+ // check that RIP was not improperly advanced and that the
+ // flags value was preserved.
+ report("RIP has not been advanced!",
+ regs->rip < finish_fault);
+ report("The low byte of RFLAGS was preserved!",
+ ((u8)regs->rflags == ((sentinel | 2) & 0xd7)));
+
+ regs->rip = finish_fault;
+ handler_called = true;
+
+}
+
+static void prep_flags_test_env(void **vpage, struct vmcs **vmcs, handler *old)
+{
+ // get an unbacked address that will cause a #PF
+ *vpage = alloc_vpage();
+
+ // set up VMCS so we have something to read from
+ *vmcs = alloc_page();
+
+ memset(*vmcs, 0, PAGE_SIZE);
+ (*vmcs)->hdr.revision_id = basic.revision;
+ assert(!vmcs_clear(*vmcs));
+ assert(!make_vmcs_current(*vmcs));
+
+ *old = handle_exception(PF_VECTOR, &pf_handler);
+}
+
+static void test_read_sentinel(void)
+{
+ void *vpage;
+ struct vmcs *vmcs;
+ handler old;
+
+ prep_flags_test_env(&vpage, &vmcs, &old);
+
+ // set the proper label
+ extern char finish_read_fault;
+
+ finish_fault = (ulong)&finish_read_fault;
+
+ // execute the vmread instruction that will cause a #PF
+ handler_called = false;
+ asm volatile ("movb %[byte], %%ah\n\t"
+ "sahf\n\t"
+ "vmread %[enc], %[val]; finish_read_fault:"
+ : [val] "=m" (*(u64 *)vpage)
+ : [byte] "Krm" (sentinel),
+ [enc] "r" ((u64)GUEST_SEL_SS)
+ : "cc", "ah"
+ );
+ report("The #PF handler was invoked", handler_called);
+
+ // restore old #PF handler
+ handle_exception(PF_VECTOR, old);
+}
+
+static void test_vmread_flags_touch(void)
+{
+ // set up the sentinel value in the flags register. we
+ // choose these two values because they candy-stripe
+ // the 5 flags that sahf sets.
+ sentinel = 0x91;
+ test_read_sentinel();
+
+ sentinel = 0x45;
+ test_read_sentinel();
+}
+
+static void test_write_sentinel(void)
+{
+ void *vpage;
+ struct vmcs *vmcs;
+ handler old;
+
+ prep_flags_test_env(&vpage, &vmcs, &old);
+
+ // set the proper label
+ extern char finish_write_fault;
+
+ finish_fault = (ulong)&finish_write_fault;
+
+ // execute the vmwrite instruction that will cause a #PF
+ handler_called = false;
+ asm volatile ("movb %[byte], %%ah\n\t"
+ "sahf\n\t"
+ "vmwrite %[val], %[enc]; finish_write_fault:"
+ : [val] "=m" (*(u64 *)vpage)
+ : [byte] "Krm" (sentinel),
+ [enc] "r" ((u64)GUEST_SEL_SS)
+ : "cc", "ah"
+ );
+ report("The #PF handler was invoked", handler_called);
+
+ // restore old #PF handler
+ handle_exception(PF_VECTOR, old);
+}
+
+static void test_vmwrite_flags_touch(void)
+{
+ // set up the sentinel value in the flags register. we
+ // choose these two values because they candy-stripe
+ // the 5 flags that sahf sets.
+ sentinel = 0x91;
+ test_write_sentinel();
+
+ sentinel = 0x45;
+ test_write_sentinel();
+}
+
+
static void test_vmcs_high(void)
{
struct vmcs *vmcs = alloc_page();
@@ -1994,6 +2111,10 @@ int main(int argc, const char *argv[])
test_vmcs_lifecycle();
if (test_wanted("test_vmx_caps", argv, argc))
test_vmx_caps();
+ if (test_wanted("test_vmread_flags_touch", argv, argc))
+ test_vmread_flags_touch();
+ if (test_wanted("test_vmwrite_flags_touch", argv, argc))
+ test_vmwrite_flags_touch();
/* Balance vmxon from test_vmxon. */
vmx_off();
--
2.26.0.110.g2183baf09c-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation
2020-04-13 17:24 [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation Simon Smith
@ 2020-04-13 23:50 ` Sean Christopherson
2020-04-13 23:52 ` Jim Mattson
0 siblings, 1 reply; 4+ messages in thread
From: Sean Christopherson @ 2020-04-13 23:50 UTC (permalink / raw)
To: Simon Smith; +Cc: kvm, pbonzini, Jim Mattson, Peter Shier, Krish Sadhukhan
s/gtest/nVMX for the shortlog. I thought this was somehow related to the
Google Test framework, especially coming from a @google.com address.
On Mon, Apr 13, 2020 at 10:24:32AM -0700, Simon Smith wrote:
> This commit adds new unit tests for commit a4d956b93904 ("KVM: nVMX:
> vmread should not set rflags to specify success in case of #PF")
>
> The two new tests force a vmread and a vmwrite on an unmapped
> address to cause a #PF and verify that the low byte of %rflags is
> preserved and that %rip is not advanced. The cherry-pick fixed a
> bug in vmread, but we include a test for vmwrite as well for
> completeness.
I think some of Google's process is bleeding into kvm-unit-tests, I'm pretty
sure the aforementioned commit wasn't cherry-picked into Paolo's tree. :-D
> Before the aforementioned commit, the ALU flags would be incorrectly
> cleared and %rip would be advanced (for vmread).
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation
2020-04-13 23:50 ` Sean Christopherson
@ 2020-04-13 23:52 ` Jim Mattson
2020-04-13 23:55 ` Jim Mattson
0 siblings, 1 reply; 4+ messages in thread
From: Jim Mattson @ 2020-04-13 23:52 UTC (permalink / raw)
To: Sean Christopherson
Cc: Simon Smith, kvm list, Paolo Bonzini, Peter Shier,
Krish Sadhukhan
On Mon, Apr 13, 2020 at 4:50 PM Sean Christopherson
<sean.j.christopherson@intel.com> wrote:
>
> s/gtest/nVMX for the shortlog. I thought this was somehow related to the
> Google Test framework, especially coming from a @google.com address.
>
> On Mon, Apr 13, 2020 at 10:24:32AM -0700, Simon Smith wrote:
> > This commit adds new unit tests for commit a4d956b93904 ("KVM: nVMX:
> > vmread should not set rflags to specify success in case of #PF")
> >
> > The two new tests force a vmread and a vmwrite on an unmapped
> > address to cause a #PF and verify that the low byte of %rflags is
> > preserved and that %rip is not advanced. The cherry-pick fixed a
> > bug in vmread, but we include a test for vmwrite as well for
> > completeness.
>
> I think some of Google's process is bleeding into kvm-unit-tests, I'm pretty
> sure the aforementioned commit wasn't cherry-picked into Paolo's tree. :-D
I see it in Linus' tree.
> > Before the aforementioned commit, the ALU flags would be incorrectly
> > cleared and %rip would be advanced (for vmread).
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation
2020-04-13 23:52 ` Jim Mattson
@ 2020-04-13 23:55 ` Jim Mattson
0 siblings, 0 replies; 4+ messages in thread
From: Jim Mattson @ 2020-04-13 23:55 UTC (permalink / raw)
To: Sean Christopherson
Cc: Simon Smith, kvm list, Paolo Bonzini, Peter Shier,
Krish Sadhukhan
On Mon, Apr 13, 2020 at 4:52 PM Jim Mattson <jmattson@google.com> wrote:
>
> On Mon, Apr 13, 2020 at 4:50 PM Sean Christopherson
> <sean.j.christopherson@intel.com> wrote:
> >
> > s/gtest/nVMX for the shortlog. I thought this was somehow related to the
> > Google Test framework, especially coming from a @google.com address.
> >
> > On Mon, Apr 13, 2020 at 10:24:32AM -0700, Simon Smith wrote:
> > > This commit adds new unit tests for commit a4d956b93904 ("KVM: nVMX:
> > > vmread should not set rflags to specify success in case of #PF")
> > >
> > > The two new tests force a vmread and a vmwrite on an unmapped
> > > address to cause a #PF and verify that the low byte of %rflags is
> > > preserved and that %rip is not advanced. The cherry-pick fixed a
> > > bug in vmread, but we include a test for vmwrite as well for
> > > completeness.
> >
> > I think some of Google's process is bleeding into kvm-unit-tests, I'm pretty
> > sure the aforementioned commit wasn't cherry-picked into Paolo's tree. :-D
>
> I see it in Linus' tree.
Oh, I see what you mean. s/cherry-pick/commit/.
> > > Before the aforementioned commit, the ALU flags would be incorrectly
> > > cleared and %rip would be advanced (for vmread).
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-04-13 23:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-13 17:24 [kvm-unit-tests RESEND PATCH] x86: gtests: add new test for vmread/vmwrite flags preservation Simon Smith
2020-04-13 23:50 ` Sean Christopherson
2020-04-13 23:52 ` Jim Mattson
2020-04-13 23:55 ` Jim Mattson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox