public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	 David Matlack <dmatlack@google.com>,
	Pasha Tatashin <tatashin@google.com>,
	 Michael Krebs <mkrebs@google.com>
Subject: [PATCH 2/2] KVM: selftests: Test forced instruction emulation in dirty log test (x86 only)
Date: Wed, 14 Feb 2024 17:00:04 -0800	[thread overview]
Message-ID: <20240215010004.1456078-3-seanjc@google.com> (raw)
In-Reply-To: <20240215010004.1456078-1-seanjc@google.com>

Add forced emulation of MOV and LOCK CMPXCHG instructions in the dirty log
test's guest code to verify that KVM's emulator marks pages dirty as
expected (and obviously to verify the emulator works at all).  In the long
term, the guest code would ideally hammer more of KVM's emulator, but for
starters, cover the two major paths: writes and atomics.

To minimize #ifdeffery, wrap only the related code that is x86 specific,
unnecessariliy synchronizing an extra boolean to the guest is far from the
end of the world.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 tools/testing/selftests/kvm/dirty_log_test.c | 36 ++++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c
index eaad5b20854c..ff1d1c7f05d8 100644
--- a/tools/testing/selftests/kvm/dirty_log_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_test.c
@@ -92,6 +92,29 @@ static uint64_t guest_test_phys_mem;
  */
 static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM;
 
+static bool is_forced_emulation_enabled;
+
+static void guest_write_memory(uint64_t *mem, uint64_t val, uint64_t rand)
+{
+#ifdef __x86_64__
+	if (is_forced_emulation_enabled && (rand & 1)) {
+		if (rand & 2) {
+			__asm__ __volatile__(KVM_FEP "movq %1, %0"
+					     : "+m" (*mem)
+					     : "r" (val) : "memory");
+		} else {
+			uint64_t __old = READ_ONCE(*mem);
+
+			__asm__ __volatile__(KVM_FEP LOCK_PREFIX "cmpxchgq %[new], %[ptr]"
+					     : [ptr] "+m" (*mem), [old] "+a" (__old)
+					     : [new]"r" (val) : "memory", "cc");
+		}
+	} else
+#endif
+
+	*mem = val;
+}
+
 /*
  * Continuously write to the first 8 bytes of a random pages within
  * the testing memory region.
@@ -114,11 +137,13 @@ static void guest_code(void)
 
 	while (true) {
 		for (i = 0; i < TEST_PAGES_PER_LOOP; i++) {
+			uint64_t rand = READ_ONCE(random_array[i]);
+
 			addr = guest_test_virt_mem;
-			addr += (READ_ONCE(random_array[i]) % guest_num_pages)
-				* guest_page_size;
+			addr += (rand % guest_num_pages) * guest_page_size;
 			addr = align_down(addr, host_page_size);
-			*(uint64_t *)addr = READ_ONCE(iteration);
+
+			guest_write_memory((void *)addr, READ_ONCE(iteration), rand);
 		}
 
 		/* Tell the host that we need more random numbers */
@@ -772,6 +797,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 	sync_global_to_guest(vm, guest_page_size);
 	sync_global_to_guest(vm, guest_test_virt_mem);
 	sync_global_to_guest(vm, guest_num_pages);
+	sync_global_to_guest(vm, is_forced_emulation_enabled);
 
 	/* Start the iterations */
 	iteration = 1;
@@ -875,6 +901,10 @@ int main(int argc, char *argv[])
 	int opt, i;
 	sigset_t sigset;
 
+#ifdef __x86_64__
+	is_forced_emulation_enabled = kvm_is_forced_emulation_enabled();
+#endif
+
 	sem_init(&sem_vcpu_stop, 0, 0);
 	sem_init(&sem_vcpu_cont, 0, 0);
 
-- 
2.43.0.687.g38aa6559b0-goog


  parent reply	other threads:[~2024-02-15  1:00 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-15  1:00 [PATCH 0/2] KVM: x86: Fix dirty logging of emulated atomics Sean Christopherson
2024-02-15  1:00 ` [PATCH 1/2] KVM: x86: Mark target gfn of emulated atomic instruction as dirty Sean Christopherson
2024-02-15 17:13   ` Jim Mattson
2024-02-15 17:57   ` David Matlack
2024-02-15 18:45     ` Sean Christopherson
2024-02-16 17:10       ` Sean Christopherson
2024-02-16 17:14         ` David Matlack
2024-02-15  1:00 ` Sean Christopherson [this message]
2024-02-15  8:21   ` [PATCH 2/2] KVM: selftests: Test forced instruction emulation in dirty log test (x86 only) Oliver Upton
2024-02-15 18:50     ` Sean Christopherson
2024-02-15 20:13       ` Oliver Upton
2024-02-15 21:33         ` Sean Christopherson
2024-02-15 23:27           ` Oliver Upton
2024-02-16  0:26             ` Sean Christopherson
2024-02-16 15:55               ` Oliver Upton
2024-02-16 17:03                 ` Sean Christopherson
2024-02-17  1:02 ` [PATCH 0/2] KVM: x86: Fix dirty logging of emulated atomics Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240215010004.1456078-3-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=dmatlack@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mkrebs@google.com \
    --cc=pbonzini@redhat.com \
    --cc=tatashin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox