Since paravirt preempt is also applied, I applied this one with some modifications, you can check whether it is correct.
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git/commit/?h=loongarch-kvm&id=cf991b57ffc808d69cb1f911563b1d4658774ccf Huacai On Thu, Jan 29, 2026 at 10:18 AM Bibo Mao <[email protected]> wrote: > > LoongArch KVM supports steal time accounting now, here add steal time > test case on LoongArch. > > Signed-off-by: Bibo Mao <[email protected]> > --- > tools/testing/selftests/kvm/Makefile.kvm | 1 + > tools/testing/selftests/kvm/steal_time.c | 85 ++++++++++++++++++++++++ > 2 files changed, 86 insertions(+) > > diff --git a/tools/testing/selftests/kvm/Makefile.kvm > b/tools/testing/selftests/kvm/Makefile.kvm > index ba5c2b643efa..a18c00f1a4fa 100644 > --- a/tools/testing/selftests/kvm/Makefile.kvm > +++ b/tools/testing/selftests/kvm/Makefile.kvm > @@ -228,6 +228,7 @@ TEST_GEN_PROGS_loongarch += kvm_page_table_test > TEST_GEN_PROGS_loongarch += memslot_modification_stress_test > TEST_GEN_PROGS_loongarch += memslot_perf_test > TEST_GEN_PROGS_loongarch += set_memory_region_test > +TEST_GEN_PROGS_loongarch += steal_time > > SPLIT_TESTS += arch_timer > SPLIT_TESTS += get-reg-list > diff --git a/tools/testing/selftests/kvm/steal_time.c > b/tools/testing/selftests/kvm/steal_time.c > index 8edc1fca345b..ee13e8973c45 100644 > --- a/tools/testing/selftests/kvm/steal_time.c > +++ b/tools/testing/selftests/kvm/steal_time.c > @@ -301,6 +301,91 @@ static void steal_time_dump(struct kvm_vm *vm, uint32_t > vcpu_idx) > pr_info("\n"); > } > > +#elif defined(__loongarch__) > +/* steal_time must have 64-byte alignment */ > +#define STEAL_TIME_SIZE ((sizeof(struct kvm_steal_time) + 63) > & ~63) > +#define KVM_STEAL_PHYS_VALID BIT_ULL(0) > + > +struct kvm_steal_time { > + __u64 steal; > + __u32 version; > + __u32 flags; > + __u32 pad[12]; > +}; > + > +static bool is_steal_time_supported(struct kvm_vcpu *vcpu) > +{ > + int err; > + uint64_t val; > + struct kvm_device_attr attr = { > + .group = KVM_LOONGARCH_VCPU_CPUCFG, > + .attr = CPUCFG_KVM_FEATURE, > + .addr = (uint64_t)&val, > + }; > + > + err = __vcpu_ioctl(vcpu, KVM_HAS_DEVICE_ATTR, &attr); > + if (err) > + return false; > + > + err = __vcpu_ioctl(vcpu, KVM_GET_DEVICE_ATTR, &attr); > + if (err) > + return false; > + > + return val & BIT(KVM_FEATURE_STEAL_TIME); > +} > + > +static void steal_time_init(struct kvm_vcpu *vcpu, uint32_t i) > +{ > + struct kvm_vm *vm = vcpu->vm; > + uint64_t st_gpa; > + int err; > + struct kvm_device_attr attr = { > + .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL, > + .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA, > + .addr = (uint64_t)&st_gpa, > + }; > + > + /* ST_GPA_BASE is identity mapped */ > + st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE); > + sync_global_to_guest(vm, st_gva[i]); > + > + err = __vcpu_ioctl(vcpu, KVM_HAS_DEVICE_ATTR, &attr); > + TEST_ASSERT(err == 0, "No PV stealtime Feature"); > + > + st_gpa = (unsigned long)st_gva[i] | KVM_STEAL_PHYS_VALID; > + err = __vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &attr); > + TEST_ASSERT(err == 0, "Fail to set PV stealtime GPA"); > +} > + > +static void guest_code(int cpu) > +{ > + struct kvm_steal_time *st = st_gva[cpu]; > + uint32_t version; > + > + memset(st, 0, sizeof(*st)); > + GUEST_SYNC(0); > + > + GUEST_ASSERT(!(READ_ONCE(st->version) & 1)); > + WRITE_ONCE(guest_stolen_time[cpu], st->steal); > + version = READ_ONCE(st->version); > + GUEST_ASSERT(!(READ_ONCE(st->version) & 1)); > + GUEST_SYNC(1); > + > + GUEST_ASSERT(!(READ_ONCE(st->version) & 1)); > + GUEST_ASSERT(version < READ_ONCE(st->version)); > + WRITE_ONCE(guest_stolen_time[cpu], st->steal); > + GUEST_ASSERT(!(READ_ONCE(st->version) & 1)); > + GUEST_DONE(); > +} > + > +static void steal_time_dump(struct kvm_vm *vm, uint32_t vcpu_idx) > +{ > + struct kvm_steal_time *st = addr_gva2hva(vm, (ulong)st_gva[vcpu_idx]); > + > + ksft_print_msg("VCPU%d:\n", vcpu_idx); > + ksft_print_msg(" steal: %lld\n", st->steal); > + ksft_print_msg(" version: %d\n", st->version); > +} > #endif > > static void *do_steal_time(void *arg) > > base-commit: 8dfce8991b95d8625d0a1d2896e42f93b9d7f68d > -- > 2.39.3 >

