On Mon, Feb 2, 2026 at 10:03 AM Bibo Mao <[email protected]> wrote: > > Hi Huacai, > > On 2026/1/31 下午9:47, Huacai Chen wrote: > > 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 > > I checked the pendning patches in loongarch-kvm branch, they all look > good to me. OK, then are there any updates on this one? https://lore.kernel.org/loongarch/caahv-h57b14qy+5jqe+fd5ftqq6jrhurfnbcqbqwg6supkf...@mail.gmail.com/T/#t
Huacai > > Thanks for doing this. > > Regards > Bibo Mao > > > > 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 > >> > >

