* [PATCH v3 0/2] KVM: LoongArch: selftests: Add FPU test case
@ 2026-06-16 2:26 Bibo Mao
2026-06-16 2:26 ` [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method Bibo Mao
2026-06-16 2:26 ` [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
0 siblings, 2 replies; 5+ messages in thread
From: Bibo Mao @ 2026-06-16 2:26 UTC (permalink / raw)
To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel, linux-kselftest
Here add FPU test case and verify FPU register get and set APIs, the
FPU width supports 64/128/256 bits. It is important for VM migration.
---
v2 ... v3:
1. Remove __vm_has_feature() and use __kvm_has_device_attr() directly
when checking LSX/LASX feature in patch 2.
v1 ... v2:
1. Replace hardcode value with CSR_EUEN_XXX when enable FPU access.
2. Add attribute __aligned(64) with kvm_fpureg variable with better FPU
save and restore.
3. Add clobber $f0 register with inline assemble language with
fld.d/vld/xvld instruction.
4. Add fallthrough between UCALL_DONE and UCALL_SYNC switch case
sentences.
5. Remove sync_global_from_guest() between vcpu_fpu_get() ioctl test
case, since the buffer is not modified with such instructions
fld.d/vld/xvld.
6. Modify FPU register with random value rather than plus 0x10, and
random() is replaced with value 0x10.
---
Bibo Mao (2):
KVM: LoongArch: selftests: Enable LASX feature by auto detect method
KVM: LoongArch: selftests: Add FPU test case
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/include/loongarch/processor.h | 18 +++
.../selftests/kvm/lib/loongarch/processor.c | 12 +-
.../selftests/kvm/loongarch/fpu_test.c | 138 ++++++++++++++++++
4 files changed, 168 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/kvm/loongarch/fpu_test.c
base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
--
2.39.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method
2026-06-16 2:26 [PATCH v3 0/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
@ 2026-06-16 2:26 ` Bibo Mao
2026-06-16 2:39 ` sashiko-bot
2026-06-16 2:26 ` [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
1 sibling, 1 reply; 5+ messages in thread
From: Bibo Mao @ 2026-06-16 2:26 UTC (permalink / raw)
To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel, linux-kselftest
Add LSX and LASX features when VM is created. These features are detected
firstly, enable it if it is available on host machine.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
.../selftests/kvm/include/loongarch/processor.h | 10 ++++++++++
.../testing/selftests/kvm/lib/loongarch/processor.c | 12 +++++++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/tools/testing/selftests/kvm/include/loongarch/processor.h
index 93dc1fbd2e79..2324e311180f 100644
--- a/tools/testing/selftests/kvm/include/loongarch/processor.h
+++ b/tools/testing/selftests/kvm/include/loongarch/processor.h
@@ -131,6 +131,16 @@
#define CSR_TLBREHI_PS_SHIFT 0
#define CSR_TLBREHI_PS (0x3fUL << CSR_TLBREHI_PS_SHIFT)
+#define LOONGARCH_CPUCFG2 0x2
+#define CPUCFG2_FP BIT(0)
+#define CPUCFG2_FPSP BIT(1)
+#define CPUCFG2_FPDP BIT(2)
+#define CPUCFG2_FPVERS GENMASK(5, 3)
+#define CPUCFG2_LSX BIT(6)
+#define CPUCFG2_LASX BIT(7)
+#define CPUCFG2_LLFTP BIT(14)
+#define CPUCFG2_LLFTPREV GENMASK(17, 15)
+
#define read_cpucfg(reg) \
({ \
register unsigned long __v; \
diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/testing/selftests/kvm/lib/loongarch/processor.c
index 64d91fb76522..e7fb54d746f4 100644
--- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
+++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
@@ -278,7 +278,7 @@ static void loongarch_set_csr(struct kvm_vcpu *vcpu, u64 id, u64 val)
void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
{
- int width;
+ int width, ret;
unsigned int cfg;
unsigned long val;
struct kvm_vm *vm = vcpu->vm;
@@ -292,6 +292,16 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
}
+ /* Enable LSX/LASX feature by detecting host capability */
+ cfg = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | CPUCFG2_LLFTP;
+ ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LSX);
+ if (!ret)
+ cfg |= CPUCFG2_LSX;
+
+ ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LASX);
+ if (!ret)
+ cfg |= CPUCFG2_LASX;
+ loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG2, cfg);
cfg = read_cpucfg(LOONGARCH_CPUCFG6);
loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG6, cfg);
--
2.39.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case
2026-06-16 2:26 [PATCH v3 0/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
2026-06-16 2:26 ` [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method Bibo Mao
@ 2026-06-16 2:26 ` Bibo Mao
2026-06-16 2:34 ` sashiko-bot
1 sibling, 1 reply; 5+ messages in thread
From: Bibo Mao @ 2026-06-16 2:26 UTC (permalink / raw)
To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel, linux-kselftest
Add FPU test case and verify FPU register get and set APIs, the
FPU width supports 64/128/256 bits.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/include/loongarch/processor.h | 8 +
.../selftests/kvm/loongarch/fpu_test.c | 138 ++++++++++++++++++
3 files changed, 147 insertions(+)
create mode 100644 tools/testing/selftests/kvm/loongarch/fpu_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 9118a5a51b89..7d11592b3759 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -224,6 +224,7 @@ TEST_GEN_PROGS_riscv += rseq_test
TEST_GEN_PROGS_riscv += steal_time
TEST_GEN_PROGS_loongarch = loongarch/pmu_test
+TEST_GEN_PROGS_loongarch += loongarch/fpu_test
TEST_GEN_PROGS_loongarch += arch_timer
TEST_GEN_PROGS_loongarch += coalesced_io_test
TEST_GEN_PROGS_loongarch += demand_paging_test
diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/tools/testing/selftests/kvm/include/loongarch/processor.h
index 2324e311180f..981ae7078354 100644
--- a/tools/testing/selftests/kvm/include/loongarch/processor.h
+++ b/tools/testing/selftests/kvm/include/loongarch/processor.h
@@ -82,6 +82,14 @@
#define PLV_MASK 0x3
#define LOONGARCH_CSR_PRMD 0x1
#define LOONGARCH_CSR_EUEN 0x2
+#define CSR_EUEN_LBTEN_SHIFT 3
+#define CSR_EUEN_LBTEN BIT_ULL(CSR_EUEN_LBTEN_SHIFT)
+#define CSR_EUEN_LASXEN_SHIFT 2
+#define CSR_EUEN_LASXEN BIT_ULL(CSR_EUEN_LASXEN_SHIFT)
+#define CSR_EUEN_LSXEN_SHIFT 1
+#define CSR_EUEN_LSXEN BIT_ULL(CSR_EUEN_LSXEN_SHIFT)
+#define CSR_EUEN_FPEN_SHIFT 0
+#define CSR_EUEN_FPEN BIT_ULL(CSR_EUEN_FPEN_SHIFT)
#define LOONGARCH_CSR_ECFG 0x4
#define ECFGB_PMU 10
#define ECFGF_PMU (BIT_ULL(ECFGB_PMU))
diff --git a/tools/testing/selftests/kvm/loongarch/fpu_test.c b/tools/testing/selftests/kvm/loongarch/fpu_test.c
new file mode 100644
index 000000000000..fe58ed4f93c0
--- /dev/null
+++ b/tools/testing/selftests/kvm/loongarch/fpu_test.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <string.h>
+#include "kvm_util.h"
+#include "processor.h"
+#include "loongarch/processor.h"
+
+struct kvm_fpureg __aligned(64) vector = {{1, 2, 3, 4 }};
+
+static void guest_code(void)
+{
+ unsigned long val;
+ struct kvm_fpureg *fp = &vector;
+
+ val = csr_read(LOONGARCH_CSR_EUEN);
+ val |= CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN;
+ csr_write(val, LOONGARCH_CSR_EUEN);
+
+ __asm__ __volatile__("fld.d $f0, %0, 0\n" : : "r"(fp) : "$f0");
+ GUEST_SYNC(0);
+
+ __asm__ __volatile__("vld $vr0, %0, 0\n" : : "r"(fp) : "$vr0");
+ GUEST_SYNC(1);
+
+ __asm__ __volatile__("xvld $xr0, %0, 0\n" : : "r"(fp) : "$xr0");
+ GUEST_SYNC(2);
+
+ __asm__ __volatile__("fst.d $f0, %0, 0\n" : : "r"(fp) : "memory");
+ GUEST_SYNC(3);
+
+ __asm__ __volatile__("vst $vr0, %0, 0\n" : : "r"(fp) : "memory");
+ GUEST_SYNC(4);
+
+ __asm__ __volatile__("xvst $xr0, %0, 0\n" : : "r"(fp) : "memory");
+ GUEST_SYNC(5);
+
+ GUEST_DONE();
+}
+
+static void run_vcpu(struct kvm_vcpu *vcpu)
+{
+ struct ucall uc;
+ int cont;
+
+ cont = 1;
+ while (cont) {
+ vcpu_run(vcpu);
+
+ switch (get_ucall(vcpu, &uc)) {
+ case UCALL_PRINTF:
+ printf("%s", (const char *)uc.buffer);
+ break;
+ case UCALL_DONE:
+ printf("FPU test PASSED\n");
+ fallthrough;
+ case UCALL_SYNC:
+ cont = 0;
+ break;
+ case UCALL_ABORT:
+ REPORT_GUEST_ASSERT(uc);
+ default:
+ TEST_ASSERT(false, "Unexpected exit: %s",
+ exit_reason_str(vcpu->run->exit_reason));
+ }
+ }
+}
+
+int main(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+ struct kvm_fpu fpu;
+ struct kvm_fpureg *fp = &vector;
+ int ret;
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+ ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LSX);
+ __TEST_REQUIRE(!ret, "LSX not available, skipping test\n");
+
+ ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LASX);
+ __TEST_REQUIRE(!ret, "LASX not available, skipping test\n");
+
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 8), "Wanted 0x%llx from f0, got 0x%llx",
+ fp->val64[0], fpu.fpr[0].val64[0]);
+
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 16), "Wanted 0x%llx %llx from vr0, got 0x%llx %llx",
+ fp->val64[0], fp->val64[1],
+ fpu.fpr[0].val64[0], fpu.fpr[0].val64[1]);
+
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 32),
+ "Wanted 0x%llx %llx %llx %llx from xr0, got 0x%llx %llx %llx %llx",
+ fp->val64[0], fp->val64[1], fp->val64[2], fp->val64[3],
+ fpu.fpr[0].val64[0], fpu.fpr[0].val64[1],
+ fpu.fpr[0].val64[2], fpu.fpr[0].val64[3]);
+
+ fpu.fpr[0].val64[0] += random();
+ vcpu_fpu_set(vcpu, &fpu);
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ sync_global_from_guest(vm, *fp);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 8), "Wanted 0x%llx from f0, got 0x%llx",
+ fp->val64[0], fpu.fpr[0].val64[0]);
+
+ fpu.fpr[0].val64[0] += random();
+ fpu.fpr[0].val64[1] += random();
+ vcpu_fpu_set(vcpu, &fpu);
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ sync_global_from_guest(vm, *fp);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 16), "Wanted 0x%llx %llx from vr0, got 0x%llx %llx",
+ fp->val64[0], fp->val64[1],
+ fpu.fpr[0].val64[0], fpu.fpr[0].val64[1]);
+
+ fpu.fpr[0].val64[0] += random();
+ fpu.fpr[0].val64[1] += random();
+ fpu.fpr[0].val64[2] += random();
+ fpu.fpr[0].val64[3] += random();
+ vcpu_fpu_set(vcpu, &fpu);
+ run_vcpu(vcpu);
+ vcpu_fpu_get(vcpu, &fpu);
+ sync_global_from_guest(vm, *fp);
+ TEST_ASSERT(!memcmp(fpu.fpr, fp, 32),
+ "Wanted 0x%llx %llx %llx %llx from xr0, got 0x%llx %llx %llx %llx",
+ fp->val64[0], fp->val64[1], fp->val64[2], fp->val64[3],
+ fpu.fpr[0].val64[0], fpu.fpr[0].val64[1],
+ fpu.fpr[0].val64[2], fpu.fpr[0].val64[3]);
+
+ run_vcpu(vcpu);
+ kvm_vm_free(vm);
+ return 0;
+}
--
2.39.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case
2026-06-16 2:26 ` [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
@ 2026-06-16 2:34 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-06-16 2:34 UTC (permalink / raw)
To: Bibo Mao; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] FPU selftest fails to verify that `vcpu_fpu_set` actually modifies the vCPU FPU state.
--
commit 2bf4caa3158a9fa987285bf7aea2092fe7c8a3f7
Author: Bibo Mao <maobibo@loongson.cn>
KVM: LoongArch: selftests: Add FPU test case
This commit adds an FPU test case to verify FPU register get and set APIs
for LoongArch. It supports testing 64, 128, and 256-bit FPU widths.
> diff --git a/tools/testing/selftests/kvm/loongarch/fpu_test.c b/tools/testing/selftests/kvm/loongarch/fpu_test.c
> new file mode 100644
> index 0000000000000..fe58ed4f93c0b
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/loongarch/fpu_test.c
[ ... ]
> +int main(void)
> +{
[ ... ]
> + fpu.fpr[0].val64[0] += random();
> + vcpu_fpu_set(vcpu, &fpu);
> + run_vcpu(vcpu);
> + vcpu_fpu_get(vcpu, &fpu);
> + sync_global_from_guest(vm, *fp);
> + TEST_ASSERT(!memcmp(fpu.fpr, fp, 8), "Wanted 0x%llx from f0, got 0x%llx",
> + fp->val64[0], fpu.fpr[0].val64[0]);
[Severity: Medium]
Does this sequence actually verify the set operation?
The test adds random() to the fpu structure and calls vcpu_fpu_set(). However,
it then updates both the fpu structure via vcpu_fpu_get() and the fp structure
via sync_global_from_guest() before comparing them against each other.
If vcpu_fpu_set() silently fails or does nothing, won't both structures just
read back the previous, unmodified state and cause the memcmp() to pass anyway?
It looks like this pattern repeats for the 128-bit and 256-bit checks below as
well.
> +
> + fpu.fpr[0].val64[0] += random();
> + fpu.fpr[0].val64[1] += random();
> + vcpu_fpu_set(vcpu, &fpu);
> + run_vcpu(vcpu);
> + vcpu_fpu_get(vcpu, &fpu);
> + sync_global_from_guest(vm, *fp);
> + TEST_ASSERT(!memcmp(fpu.fpr, fp, 16), "Wanted 0x%llx %llx from vr0, got 0x%llx %llx",
> + fp->val64[0], fp->val64[1],
> + fpu.fpr[0].val64[0], fpu.fpr[0].val64[1]);
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616022615.2141072-1-maobibo@loongson.cn?part=2
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method
2026-06-16 2:26 ` [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method Bibo Mao
@ 2026-06-16 2:39 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-06-16 2:39 UTC (permalink / raw)
To: Bibo Mao; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Hardcoding the base CPUCFG2 value silently clears FPU version, LLFTP revision, and other default KVM features.
--
commit 7ccc915fb84c033373faa2df43f4b5551f11c4d3
Author: Bibo Mao <maobibo@loongson.cn>
KVM: LoongArch: selftests: Enable LASX feature by auto detect method
This commit enables LSX and LASX features for LoongArch KVM selftests when
the host machine supports them.
> diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/testing/selftests/kvm/lib/loongarch/processor.c
> index 64d91fb76522d..e7fb54d746f45 100644
> --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
> +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
[ ... ]
> @@ -292,6 +292,16 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
> TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
> }
>
> + /* Enable LSX/LASX feature by detecting host capability */
> + cfg = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | CPUCFG2_LLFTP;
> + ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LSX);
> + if (!ret)
> + cfg |= CPUCFG2_LSX;
> +
> + ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LASX);
> + if (!ret)
> + cfg |= CPUCFG2_LASX;
> + loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG2, cfg);
[Severity: Medium]
Does hardcoding the base CPUCFG2 value here inadvertently clear other default
KVM features?
Since KVM populates CPUCFG2 with defaults like CPUCFG2_FPVERS (FPU version)
and CPUCFG2_LLFTPREV (LLFTP revision) during vCPU creation, overwriting the
entire register with this bitmask might cause issues for tests or guests
relying on these standard properties.
Would it be better to read the existing KVM-provided value via vcpu_get_reg(),
bitwise-OR the detected LSX and LASX bits, and then write it back?
> cfg = read_cpucfg(LOONGARCH_CPUCFG6);
> loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG6, cfg);
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616022615.2141072-1-maobibo@loongson.cn?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-16 2:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 2:26 [PATCH v3 0/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
2026-06-16 2:26 ` [PATCH v3 1/2] KVM: LoongArch: selftests: Enable LASX feature by auto detect method Bibo Mao
2026-06-16 2:39 ` sashiko-bot
2026-06-16 2:26 ` [PATCH v3 2/2] KVM: LoongArch: selftests: Add FPU test case Bibo Mao
2026-06-16 2:34 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.