From: Dongli Zhang <dongli.zhang@oracle.com>
To: kvm@vger.kernel.org, x86@kernel.org, linux-kselftest@vger.kernel.org
Cc: seanjc@google.com, pbonzini@redhat.com, vkuznets@redhat.com,
tglx@kernel.org, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com, jgross@suse.com,
dwmw2@infradead.org, joe.jin@oracle.com
Subject: [PATCH 5/5] KVM: selftests: Test KVM_SET_CLOCK downtime in steal time
Date: Mon, 4 May 2026 17:30:18 -0700 [thread overview]
Message-ID: <20260505003044.78693-6-dongli.zhang@oracle.com> (raw)
In-Reply-To: <20260505003044.78693-1-dongli.zhang@oracle.com>
Extend kvm_clock_test to enable KVM steal time and verify that a
KVM_SET_CLOCK adjustment with KVM_CLOCK_REALTIME also advances the
guest's steal time when the realtime value is in the past.
For the negative realtime-offset case, verify that the observed steal
time delta is at least the downtime injected through KVM_SET_CLOCK.
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
---
.../selftests/kvm/x86/kvm_clock_test.c | 42 +++++++++++++++----
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/kvm_clock_test.c b/tools/testing/selftests/kvm/x86/kvm_clock_test.c
index 5ad4aeb8e373..7e0f00f21144 100644
--- a/tools/testing/selftests/kvm/x86/kvm_clock_test.c
+++ b/tools/testing/selftests/kvm/x86/kvm_clock_test.c
@@ -28,16 +28,20 @@ static struct test_case test_cases[] = {
{ .kvmclock_base = 0, .realtime_offset = 180 * NSEC_PER_SEC },
};
-#define GUEST_SYNC_CLOCK(__stage, __val) \
- GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0)
+#define GUEST_SYNC_CLOCK(__stage, __clock, __steal) \
+ GUEST_SYNC_ARGS(__stage, __clock, __steal, 0, 0)
-static void guest_main(gpa_t pvti_pa, struct pvclock_vcpu_time_info *pvti)
+static void guest_main(gpa_t pvti_pa, struct pvclock_vcpu_time_info *pvti,
+ gpa_t st_pa, struct kvm_steal_time *st)
{
int i;
wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED);
+ wrmsr(MSR_KVM_STEAL_TIME, st_pa | KVM_MSR_ENABLED);
+
for (i = 0; i < ARRAY_SIZE(test_cases); i++)
- GUEST_SYNC_CLOCK(i, __pvclock_read_cycles(pvti, rdtsc()));
+ GUEST_SYNC_CLOCK(i, __pvclock_read_cycles(pvti, rdtsc()),
+ READ_ONCE(st->steal));
}
#define EXPECTED_FLAGS (KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
@@ -50,11 +54,13 @@ static inline void assert_flags(struct kvm_clock_data *data)
}
static void handle_sync(struct ucall *uc, struct kvm_clock_data *start,
- struct kvm_clock_data *end)
+ struct kvm_clock_data *end,
+ struct test_case *test_case, u64 *last_steal)
{
- u64 obs, exp_lo, exp_hi;
+ u64 obs, exp_lo, exp_hi, obs_steal;
obs = uc->args[2];
+ obs_steal = uc->args[3];
exp_lo = start->clock;
exp_hi = end->clock;
@@ -67,6 +73,18 @@ static void handle_sync(struct ucall *uc, struct kvm_clock_data *start,
pr_info("kvm-clock value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",
obs, exp_lo, exp_hi);
+
+ if (test_case->realtime_offset < 0) {
+ u64 min_downtime = -test_case->realtime_offset;
+
+ TEST_ASSERT(obs_steal >= *last_steal &&
+ obs_steal - *last_steal >= min_downtime,
+ "unexpected steal values: obs=%"PRIu64
+ " last=%"PRIu64" min_downtime=%"PRIu64,
+ obs_steal, *last_steal, min_downtime);
+ }
+
+ *last_steal = obs_steal;
}
static void handle_abort(struct ucall *uc)
@@ -106,6 +124,7 @@ static void enter_guest(struct kvm_vcpu *vcpu)
{
struct kvm_clock_data start, end;
struct kvm_vm *vm = vcpu->vm;
+ u64 last_steal = 0;
struct ucall uc;
int i;
@@ -121,7 +140,8 @@ static void enter_guest(struct kvm_vcpu *vcpu)
switch (get_ucall(vcpu, &uc)) {
case UCALL_SYNC:
- handle_sync(&uc, &start, &end);
+ handle_sync(&uc, &start, &end,
+ &test_cases[i], &last_steal);
break;
case UCALL_ABORT:
handle_abort(&uc);
@@ -137,6 +157,8 @@ int main(void)
struct kvm_vcpu *vcpu;
gva_t pvti_gva;
gpa_t pvti_gpa;
+ gva_t st_gva;
+ gpa_t st_gpa;
struct kvm_vm *vm;
int flags;
@@ -144,12 +166,16 @@ int main(void)
TEST_REQUIRE(flags & KVM_CLOCK_REALTIME);
TEST_REQUIRE(sys_clocksource_is_based_on_tsc());
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_KVM_STEAL_TIME));
vm = vm_create_with_one_vcpu(&vcpu, guest_main);
pvti_gva = vm_alloc(vm, getpagesize(), 0x10000);
pvti_gpa = addr_gva2gpa(vm, pvti_gva);
- vcpu_args_set(vcpu, 2, pvti_gpa, pvti_gva);
+ st_gva = vm_alloc(vm, getpagesize(), 0x20000);
+ st_gpa = addr_gva2gpa(vm, st_gva);
+ memset(addr_gva2hva(vm, st_gva), 0, getpagesize());
+ vcpu_args_set(vcpu, 4, pvti_gpa, pvti_gva, st_gpa, st_gva);
enter_guest(vcpu);
kvm_vm_free(vm);
--
2.39.3
prev parent reply other threads:[~2026-05-05 0:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-05 0:30 [PATCH 0/5] Fix and enhance KVM steal accounting for both guest and host Dongli Zhang
2026-05-05 0:30 ` [PATCH 1/5] x86/kvm: Reset prev_steal_time and prev_steal_time_rq when enabling steal time Dongli Zhang
2026-05-05 0:30 ` [PATCH 2/5] KVM: x86: Reset vcpu->arch.st.last_steal " Dongli Zhang
2026-05-08 22:40 ` Sean Christopherson
2026-05-10 17:09 ` David Woodhouse
2026-05-10 18:40 ` David Woodhouse
2026-05-11 21:27 ` Dongli Zhang
2026-05-12 5:46 ` David Woodhouse
2026-05-11 21:26 ` Dongli Zhang
2026-05-05 0:30 ` [PATCH 3/5] KVM: x86: account KVM_SET_CLOCK downtime in " Dongli Zhang
2026-05-10 18:54 ` David Woodhouse
2026-05-10 19:11 ` H. Peter Anvin
2026-05-10 20:13 ` David Woodhouse
2026-05-11 21:46 ` Dongli Zhang
2026-05-12 5:34 ` David Woodhouse
2026-05-05 0:30 ` [PATCH 4/5] KVM: selftests: Test steal time when re-adding a vCPU on a new thread Dongli Zhang
2026-05-05 0:30 ` Dongli Zhang [this message]
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=20260505003044.78693-6-dongli.zhang@oracle.com \
--to=dongli.zhang@oracle.com \
--cc=bp@alien8.de \
--cc=bsegall@google.com \
--cc=dave.hansen@linux.intel.com \
--cc=dietmar.eggemann@arm.com \
--cc=dwmw2@infradead.org \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=joe.jin@oracle.com \
--cc=juri.lelli@redhat.com \
--cc=kprateek.nayak@amd.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=seanjc@google.com \
--cc=shuah@kernel.org \
--cc=tglx@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vkuznets@redhat.com \
--cc=vschneid@redhat.com \
--cc=x86@kernel.org \
/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