[PATCH v3] LoongArch: KVM: Add more CPUCFG mask bit

Bibo Mao posted 1 patch 4 days, 18 hours ago
arch/loongarch/kvm/vcpu.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
[PATCH v3] LoongArch: KVM: Add more CPUCFG mask bit
Posted by Bibo Mao 4 days, 18 hours ago
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@loongson.cn>
---
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
Re: [PATCH v3] LoongArch: KVM: Add more CPUCFG mask bit
Posted by Huacai Chen 4 days, 17 hours ago
Applied with some small changes, thanks.

Huacai

On Mon, Feb 2, 2026 at 4:26 PM Bibo Mao <maobibo@loongson.cn> 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@loongson.cn>
> ---
> 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
>
>