Re: [PATCH] KVM: LoongArch: selftests: Enable HW PTW by auto detection method

From: Huacai Chen

Date: Wed Sep 23 2026 - 00:25:44 EST


Hi, Bibo,

On Wed, Sep 23, 2026 at 9:31 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
>
> Add HW PTW feature when VM is created. This feature is detected firstly,
> enable it if it is available on host machine. With HW PTW feature enabled,
> refill exception will not happen and it is not necessary to set refill
> exception entry.
>
> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> ---
> .../selftests/kvm/include/loongarch/processor.h | 3 +++
> .../selftests/kvm/lib/loongarch/processor.c | 16 ++++++++++++++--
> 2 files changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/tools/testing/selftests/kvm/include/loongarch/processor.h
> index 0e59daa8024e..8d9fabdc89e3 100644
> --- a/tools/testing/selftests/kvm/include/loongarch/processor.h
> +++ b/tools/testing/selftests/kvm/include/loongarch/processor.h
> @@ -79,6 +79,7 @@
> #define CPUCFG2_LASX BIT(7)
> #define CPUCFG2_LLFTP BIT(14)
> #define CPUCFG2_LLFTPREV GENMASK(17, 15)
> +#define CPUCFG2_PTW BIT(24)
>
> /* LoongArch Basic CSR registers */
> #define LOONGARCH_CSR_CRMD 0x0 /* Current mode info */
> @@ -128,6 +129,8 @@
> #define LOONGARCH_CSR_PGD 0x1b
> #define LOONGARCH_CSR_PWCTL0 0x1c
> #define LOONGARCH_CSR_PWCTL1 0x1d
> +#define CSR_PWCTL1_PTW_SHIFT 24
> +#define CSR_PWCTL1_PTW BIT_ULL(CSR_PWCTL1_PTW_SHIFT)
> #define LOONGARCH_CSR_STLBPGSIZE 0x1e
> #define LOONGARCH_CSR_CPUID 0x20
> #define LOONGARCH_CSR_KS0 0x30
> diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/testing/selftests/kvm/lib/loongarch/processor.c
> index 47bbde3e205a..35e35c62759f 100644
> --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
> +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
> @@ -282,6 +282,7 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
> unsigned int cfg;
> unsigned long val;
> struct kvm_vm *vm = vcpu->vm;
> + bool has_ptw = false;
>
> switch (vm->mode) {
> case VM_MODE_P36V47_16K:
> @@ -300,6 +301,12 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
> ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_LASX);
> if (!ret)
> cfg |= CPUCFG2_LASX;
> + ret = __kvm_has_device_attr(vm->fd, KVM_LOONGARCH_VM_FEAT_CTRL, KVM_LOONGARCH_VM_FEAT_PTW);
> + if (!ret) {
> + cfg |= CPUCFG2_PTW;
> + has_ptw = true;
> + }
> +
> loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG2, cfg);
> cfg = read_cpucfg(LOONGARCH_CPUCFG6);
> loongarch_set_cpucfg(vcpu, LOONGARCH_CPUCFG6, cfg);
> @@ -338,6 +345,9 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
>
> /* PGD page shift and width */
> val = (vm->page_shift + width * (vm->mmu.pgtable_levels - 1)) | width << 6;
> + if (has_ptw)
> + val |= CSR_PWCTL1_PTW;
> +
> loongarch_set_csr(vcpu, LOONGARCH_CSR_PWCTL1, val);
> loongarch_set_csr(vcpu, LOONGARCH_CSR_PGDL, vm->mmu.pgd);
>
> @@ -345,8 +355,10 @@ void loongarch_vcpu_setup(struct kvm_vcpu *vcpu)
> * Refill exception runs on real mode
> * Entry address should be physical address
> */
> - val = addr_gva2gpa(vm, (unsigned long)handle_tlb_refill);
> - loongarch_set_csr(vcpu, LOONGARCH_CSR_TLBRENTRY, val);
> + if (!has_ptw) {
Why not just check CPUCFG2_PTW in cfg? In this way we can drop has_ptw.

Huacai

> + val = addr_gva2gpa(vm, (unsigned long)handle_tlb_refill);
> + loongarch_set_csr(vcpu, LOONGARCH_CSR_TLBRENTRY, val);
> + }
>
> /*
> * General exception runs on page-enabled mode
>
> base-commit: 93f51579e7df248780214094418f205253383cc5
> --
> 2.39.3
>