Re: [PATCH v3] LoongArch: KVM: Add more CPUCFG mask bit
From: Huacai Chen
Date: Mon Feb 02 2026 - 04:48:51 EST
Applied with some small changes, thanks.
Huacai
On Mon, Feb 2, 2026 at 4:26 PM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
>
> With LA664 CPU there are more features supported which are indicated
> in CPUCFG2 bit24:30 and CPUCFG3 bit17 and bit 23. KVM hypervisor
> cannot enable or disable these features and there is no KVM exception
> when instructions of these features are executed in guest mode.
>
> Here add more CPUCFG mask support with LA664 CPU type.
>
> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> ---
> v2 ... v3:
> 1. Add CPUCFG3_ALDORDER_STA and CPUCFG3_ASTORDER_STA in cpucfg3.
> 2. Disable bit CPUCFG3_SFB since VM does not support SFB controling.
> 3. Add checking with max supported page directory level and max virtual
> address width.
>
> v1 ... v2:
> 1. Rebase on the latest version since some common CPUCFG bit macro
> definitions are merged.
> 2. Modifiy the comments explaining why it comes from feature detect
> of host CPU.
> ---
> arch/loongarch/kvm/vcpu.c | 32 +++++++++++++++++++++++++++++---
> 1 file changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 656b954c1134..7bea5e162a4d 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -652,6 +652,8 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
>
> static int _kvm_get_cpucfg_mask(int id, u64 *v)
> {
> + unsigned int config;
> +
> if (id < 0 || id >= KVM_MAX_CPUCFG_REGS)
> return -EINVAL;
>
> @@ -684,9 +686,26 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
> if (cpu_has_ptw)
> *v |= CPUCFG2_PTW;
>
> + /*
> + * The capability indication of some features are the same
> + * between host CPU and guest vCPU, and there is no special
> + * feature detect method with vCPU. Also KVM hypervisor can
> + * not enable or disable these features.
> + *
> + * Here use host CPU detected features for vCPU
> + */
> + config = read_cpucfg(LOONGARCH_CPUCFG2);
> + *v |= config & (CPUCFG2_FRECIPE | CPUCFG2_DIV32 | CPUCFG2_LAM_BH);
> + *v |= config & (CPUCFG2_LAMCAS | CPUCFG2_LLACQ_SCREL | CPUCFG2_SCQ);
> return 0;
> case LOONGARCH_CPUCFG3:
> - *v = GENMASK(16, 0);
> + /*
> + * VM does not support memory order and SFB setting
> + * only support memory order display
> + */
> + *v = read_cpucfg(LOONGARCH_CPUCFG3) & GENMASK(23, 0);
> + *v &= ~(CPUCFG3_ALDORDER_CAP | CPUCFG3_ASTORDER_CAP | CPUCFG3_SLDORDER_CAP);
> + *v &= ~CPUCFG3_SFB;
> return 0;
> case LOONGARCH_CPUCFG4:
> case LOONGARCH_CPUCFG5:
> @@ -716,7 +735,7 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
>
> static int kvm_check_cpucfg(int id, u64 val)
> {
> - int ret;
> + int ret, host;
> u64 mask = 0;
>
> ret = _kvm_get_cpucfg_mask(id, &mask);
> @@ -746,9 +765,16 @@ static int kvm_check_cpucfg(int id, u64 val)
> /* LASX architecturally implies LSX and FP but val does not satisfy that */
> return -EINVAL;
> return 0;
> + case LOONGARCH_CPUCFG3:
> + host = read_cpucfg(LOONGARCH_CPUCFG3);
> + if ((val & CPUCFG3_SPW_LVL) > (host & CPUCFG3_SPW_LVL))
> + return -EINVAL;
> + if ((val & CPUCFG3_RVAMAX) > (host & CPUCFG3_RVAMAX))
> + return -EINVAL;
> + return 0;
> case LOONGARCH_CPUCFG6:
> if (val & CPUCFG6_PMP) {
> - u32 host = read_cpucfg(LOONGARCH_CPUCFG6);
> + host = read_cpucfg(LOONGARCH_CPUCFG6);
> if ((val & CPUCFG6_PMBITS) != (host & CPUCFG6_PMBITS))
> return -EINVAL;
> if ((val & CPUCFG6_PMNUM) > (host & CPUCFG6_PMNUM))
>
> base-commit: 18f7fcd5e69a04df57b563360b88be72471d6b62
> --
> 2.39.3
>
>