[PATCH 4/4] KVM: selftests: Add arm64 coverage for steal time pid changes

Dongli Zhang <[email protected]>
Newsgroups dev.linux.lists.kvmarm,org.kernel.vger.kvm,org.kernel.vger.linux-kselftest
Message-ID <[email protected]>
The previous patch added the common steal_time_change_pid test with x86
support. Add the arm64 support so the same test also covers arm64.

Use KVM_ARM_VCPU_PVTIME_IPA to enable the steal time shared page from
userspace, and use the PV_TIME_ST SMCCC call in the guest to retrieve and
read that page.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Dongli Zhang <[email protected]>
---
 tools/testing/selftests/kvm/Makefile.kvm      |  1 +
 .../selftests/kvm/steal_time_change_pid.c     | 54 +++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index c8ce17851561..b01a3403d602 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -199,6 +199,7 @@ TEST_GEN_PROGS_arm64 += guest_memfd_test
 TEST_GEN_PROGS_arm64 += mmu_stress_test
 TEST_GEN_PROGS_arm64 += rseq_test
 TEST_GEN_PROGS_arm64 += steal_time
+TEST_GEN_PROGS_arm64 += steal_time_change_pid
 
 TEST_GEN_PROGS_s390 = $(TEST_GEN_PROGS_COMMON)
 TEST_GEN_PROGS_s390 += s390/memop
diff --git a/tools/testing/selftests/kvm/steal_time_change_pid.c b/tools/testing/selftests/kvm/steal_time_change_pid.c
index 3c39594db398..12d4927d1c01 100644
--- a/tools/testing/selftests/kvm/steal_time_change_pid.c
+++ b/tools/testing/selftests/kvm/steal_time_change_pid.c
@@ -46,6 +46,60 @@ static void steal_time_enable(struct kvm_vcpu *vcpu)
 		     (ulong)st_gva | KVM_MSR_ENABLED);
 }
 
+#elif defined(__aarch64__)
+
+#define STEAL_TIME_SIZE	((sizeof(struct st_time) + 63) & ~63)
+
+#define PV_TIME_ST	0xc5000021
+
+struct st_time {
+	u32 rev;
+	u32 attr;
+	u64 st_time;
+};
+
+static void guest_code(void)
+{
+	struct arm_smccc_res res;
+	struct st_time *st;
+
+	do_smccc(PV_TIME_ST, 0, 0, 0, 0, 0, 0, 0, &res);
+	GUEST_ASSERT_NE(res.a0, -1);
+	GUEST_ASSERT_EQ(res.a0, (ulong)st_gva);
+
+	st = (struct st_time *)res.a0;
+	WRITE_ONCE(guest_stolen_time, READ_ONCE(st->st_time));
+	GUEST_SYNC(0);
+
+	WRITE_ONCE(guest_stolen_time, READ_ONCE(st->st_time));
+	GUEST_SYNC(1);
+
+	WRITE_ONCE(guest_stolen_time, READ_ONCE(st->st_time));
+	GUEST_DONE();
+}
+
+static bool steal_time_supported(struct kvm_vcpu *vcpu)
+{
+	struct kvm_device_attr dev = {
+		.group = KVM_ARM_VCPU_PVTIME_CTRL,
+		.attr = KVM_ARM_VCPU_PVTIME_IPA,
+	};
+
+	return !__vcpu_ioctl(vcpu, KVM_HAS_DEVICE_ATTR, &dev);
+}
+
+static void steal_time_enable(struct kvm_vcpu *vcpu)
+{
+	u64 st_ipa = (ulong)st_gva;
+	struct kvm_device_attr dev = {
+		.group = KVM_ARM_VCPU_PVTIME_CTRL,
+		.attr = KVM_ARM_VCPU_PVTIME_IPA,
+		.addr = (u64)&st_ipa,
+	};
+
+	vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &dev);
+}
+
 #else
 #error "steal_time_change_pid is not implemented on this architecture"
 #endif
-- 
2.43.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.