[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAAhV-H5yZbocBBBN5nMqb32UaVP6i8+9X4RNAwquVYVFVRaBVg@mail.gmail.com>
Date: Sat, 31 Jan 2026 21:47:58 +0800
From: Huacai Chen <chenhuacai@...nel.org>
To: Bibo Mao <maobibo@...ngson.cn>, "open list:LOONGARCH" <loongarch@...ts.linux.dev>
Cc: Paolo Bonzini <pbonzini@...hat.com>, Shuah Khan <shuah@...nel.org>, kvm@...r.kernel.org,
linux-kselftest@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] KVM: LoongArch: selftests: Add steal time test case
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 <maobibo@...ngson.cn> wrote:
>
> LoongArch KVM supports steal time accounting now, here add steal time
> test case on LoongArch.
>
> Signed-off-by: Bibo Mao <maobibo@...ngson.cn>
> ---
> 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
>
Powered by blists - more mailing lists