Re: [PATCH 01/26] KVM: arm64: Check advertised Stage-2 page size capability

2020-05-07 Thread Alexandru Elisei
Hi,

On 4/22/20 1:00 PM, Marc Zyngier wrote:
> With ARMv8.5-GTG, the hardware (or more likely a hypervisor) can
> advertise the supported Stage-2 page sizes.
>
> Let's check this at boot time.
>
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/include/asm/kvm_host.h |  2 +-
>  arch/arm64/include/asm/sysreg.h   |  3 +++
>  arch/arm64/kernel/cpufeature.c|  8 +++
>  arch/arm64/kvm/reset.c| 40 ---
>  virt/kvm/arm/arm.c|  4 +---
>  5 files changed, 50 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h 
> b/arch/arm64/include/asm/kvm_host.h
> index 32c8a675e5a4a..7dd8fefa6aecd 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -670,7 +670,7 @@ static inline int kvm_arm_have_ssbd(void)
>  void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
>  void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
>  
> -void kvm_set_ipa_limit(void);
> +int kvm_set_ipa_limit(void);
>  
>  #define __KVM_HAVE_ARCH_VM_ALLOC
>  struct kvm *kvm_arch_alloc_vm(void);
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index ebc6224328318..5d10c9148e844 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -686,6 +686,9 @@
>  #define ID_AA64ZFR0_SVEVER_SVE2  0x1
>  
>  /* id_aa64mmfr0 */
> +#define ID_AA64MMFR0_TGRAN4_2_SHIFT  40
> +#define ID_AA64MMFR0_TGRAN64_2_SHIFT 36
> +#define ID_AA64MMFR0_TGRAN16_2_SHIFT 32
>  #define ID_AA64MMFR0_TGRAN4_SHIFT28
>  #define ID_AA64MMFR0_TGRAN64_SHIFT   24
>  #define ID_AA64MMFR0_TGRAN16_SHIFT   20
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 9fac745aa7bb2..9892a845d06c9 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -208,6 +208,14 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
>  };
>  
>  static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
> + /*
> +  * Page size not being supported at Stage-2 are not fatal. You

s/are not fatal/is not fatal

> +  * just give up KVM if PAGE_SIZE isn't supported there. Go fix
> +  * your favourite nesting hypervisor.
> +  */
> + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
> ID_AA64MMFR0_TGRAN4_2_SHIFT, 4, 1),
> + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
> ID_AA64MMFR0_TGRAN64_2_SHIFT, 4, 1),
> + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
> ID_AA64MMFR0_TGRAN16_2_SHIFT, 4, 1),
>   /*
>* We already refuse to boot CPUs that don't support our configured
>* page size, so we can only detect mismatches for a page size other
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 30b7ea680f66c..241db35a7ef4f 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -340,11 +341,42 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>   return ret;
>  }
>  
> -void kvm_set_ipa_limit(void)
> +int kvm_set_ipa_limit(void)
>  {
> - unsigned int ipa_max, pa_max, va_max, parange;
> + unsigned int ipa_max, pa_max, va_max, parange, tgran_2;
> + u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
>  
> - parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 0x7;
> + /*
> +  * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
> +  * Stage-2. If not, things will stop very quickly.
> +  */
> + switch (PAGE_SIZE) {
> + default:
> + case SZ_4K:
> + tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT;
> + break;
> + case SZ_16K:
> + tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT;
> + break;
> + case SZ_64K:
> + tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT;
> + break;
> + }
> +
> + switch (FIELD_GET(0xFUL << tgran_2, mmfr0)) {
> + default:
> + case 1:
> + kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
> + return -EINVAL;
> + case 0:
> + kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n");
> + break;
> + case 2:
> + kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n");
> + break;
> + }
> +
> + parange = mmfr0 & 0x7;
>   pa_max = id_aa64mmfr0_parange_to_phys_shift(parange);
>  
>   /* Clamp the IPA limit to the PA size supported by the kernel */
> @@ -378,6 +410,8 @@ void kvm_set_ipa_limit(void)
>"KVM IPA limit (%d bit) is smaller than default size\n", ipa_max);
>   kvm_ipa_limit = ipa_max;
>   kvm_info("IPA Size Limit: %dbits\n", kvm_ipa_limit);
> +
> + return 0;
>  }
>  
>  /*
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index 48d0ec44ad77e..53b3ba9173ba7 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -1387,9 +1387,7 @@ static inline void hyp_cpu_pm_exit(void)
>  
>  stat

Re: [PATCH 01/26] KVM: arm64: Check advertised Stage-2 page size capability

2020-04-22 Thread Suzuki K Poulose

On 04/22/2020 03:07 PM, Marc Zyngier wrote:

Hi Suzuki,

On 2020-04-22 14:40, Suzuki K Poulose wrote:

Hi Marc,

On 04/22/2020 01:00 PM, Marc Zyngier wrote:

With ARMv8.5-GTG, the hardware (or more likely a hypervisor) can
advertise the supported Stage-2 page sizes.

Let's check this at boot time.

Signed-off-by: Marc Zyngier 
---
  arch/arm64/include/asm/kvm_host.h |  2 +-
  arch/arm64/include/asm/sysreg.h   |  3 +++
  arch/arm64/kernel/cpufeature.c    |  8 +++
  arch/arm64/kvm/reset.c    | 40 ---
  virt/kvm/arm/arm.c    |  4 +---
  5 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h

index 32c8a675e5a4a..7dd8fefa6aecd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,7 +670,7 @@ static inline int kvm_arm_have_ssbd(void)
  void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
  void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
  -void kvm_set_ipa_limit(void);
+int kvm_set_ipa_limit(void);
    #define __KVM_HAVE_ARCH_VM_ALLOC
  struct kvm *kvm_arch_alloc_vm(void);
diff --git a/arch/arm64/include/asm/sysreg.h 
b/arch/arm64/include/asm/sysreg.h

index ebc6224328318..5d10c9148e844 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -686,6 +686,9 @@
  #define ID_AA64ZFR0_SVEVER_SVE2    0x1
    /* id_aa64mmfr0 */
+#define ID_AA64MMFR0_TGRAN4_2_SHIFT    40
+#define ID_AA64MMFR0_TGRAN64_2_SHIFT    36
+#define ID_AA64MMFR0_TGRAN16_2_SHIFT    32
  #define ID_AA64MMFR0_TGRAN4_SHIFT    28
  #define ID_AA64MMFR0_TGRAN64_SHIFT    24
  #define ID_AA64MMFR0_TGRAN16_SHIFT    20
diff --git a/arch/arm64/kernel/cpufeature.c 
b/arch/arm64/kernel/cpufeature.c

index 9fac745aa7bb2..9892a845d06c9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -208,6 +208,14 @@ static const struct arm64_ftr_bits 
ftr_id_aa64zfr0[] = {

  };
    static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
+    /*
+ * Page size not being supported at Stage-2 are not fatal. You
+ * just give up KVM if PAGE_SIZE isn't supported there. Go fix
+ * your favourite nesting hypervisor.
+ */
+    ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN4_2_SHIFT, 4, 1),
+    ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN64_2_SHIFT, 4, 1),
+    ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN16_2_SHIFT, 4, 1),


One minor issue with this is, if we get a system with cpus having values
0 and 2 (both of which indicates the stage-2 support), we might reset
the value to 1 for the feature indicating, we don't support and block
KVM. But, we can blame the nesting hypervisor for not emulating this to
(2). Do we need a comment to make this explicit here ?


Sure. How about something like:

"There is a small corner case where the hypervisor could explicitly 
advertise
  a given granule size at Stage-2 (value 2) on some vCPUs, and use the 
fallback
  to Stage-1 (value 0) for other vCPUs. Although this is not forbidden 
by the

  architecture, it indicates that the hypervisor is being silly (or buggy).
  We make no effort to cope with this and pretend that if these fields are
  inconsistent across vCPUs, then it isn't worth trying to bring KVM up."



Looks fine to me.

Reviewed-by: Suzuki K Poulose 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH 01/26] KVM: arm64: Check advertised Stage-2 page size capability

2020-04-22 Thread Marc Zyngier

Hi Suzuki,

On 2020-04-22 14:40, Suzuki K Poulose wrote:

Hi Marc,

On 04/22/2020 01:00 PM, Marc Zyngier wrote:

With ARMv8.5-GTG, the hardware (or more likely a hypervisor) can
advertise the supported Stage-2 page sizes.

Let's check this at boot time.

Signed-off-by: Marc Zyngier 
---
  arch/arm64/include/asm/kvm_host.h |  2 +-
  arch/arm64/include/asm/sysreg.h   |  3 +++
  arch/arm64/kernel/cpufeature.c|  8 +++
  arch/arm64/kvm/reset.c| 40 
---

  virt/kvm/arm/arm.c|  4 +---
  5 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h

index 32c8a675e5a4a..7dd8fefa6aecd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,7 +670,7 @@ static inline int kvm_arm_have_ssbd(void)
  void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
  void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
  -void kvm_set_ipa_limit(void);
+int kvm_set_ipa_limit(void);
#define __KVM_HAVE_ARCH_VM_ALLOC
  struct kvm *kvm_arch_alloc_vm(void);
diff --git a/arch/arm64/include/asm/sysreg.h 
b/arch/arm64/include/asm/sysreg.h

index ebc6224328318..5d10c9148e844 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -686,6 +686,9 @@
  #define ID_AA64ZFR0_SVEVER_SVE2   0x1
/* id_aa64mmfr0 */
+#define ID_AA64MMFR0_TGRAN4_2_SHIFT40
+#define ID_AA64MMFR0_TGRAN64_2_SHIFT   36
+#define ID_AA64MMFR0_TGRAN16_2_SHIFT   32
  #define ID_AA64MMFR0_TGRAN4_SHIFT 28
  #define ID_AA64MMFR0_TGRAN64_SHIFT24
  #define ID_AA64MMFR0_TGRAN16_SHIFT20
diff --git a/arch/arm64/kernel/cpufeature.c 
b/arch/arm64/kernel/cpufeature.c

index 9fac745aa7bb2..9892a845d06c9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -208,6 +208,14 @@ static const struct arm64_ftr_bits 
ftr_id_aa64zfr0[] = {

  };
static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
+   /*
+* Page size not being supported at Stage-2 are not fatal. You
+* just give up KVM if PAGE_SIZE isn't supported there. Go fix
+* your favourite nesting hypervisor.
+*/
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN4_2_SHIFT, 4, 1),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN64_2_SHIFT, 4, 1),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN16_2_SHIFT, 4, 1),


One minor issue with this is, if we get a system with cpus having 
values

0 and 2 (both of which indicates the stage-2 support), we might reset
the value to 1 for the feature indicating, we don't support and block
KVM. But, we can blame the nesting hypervisor for not emulating this to
(2). Do we need a comment to make this explicit here ?


Sure. How about something like:

"There is a small corner case where the hypervisor could explicitly 
advertise
 a given granule size at Stage-2 (value 2) on some vCPUs, and use the 
fallback
 to Stage-1 (value 0) for other vCPUs. Although this is not forbidden by 
the
 architecture, it indicates that the hypervisor is being silly (or 
buggy).
 We make no effort to cope with this and pretend that if these fields 
are

 inconsistent across vCPUs, then it isn't worth trying to bring KVM up."

Thanks,

M.
--
Jazz is not dead. It just smells funny...
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH 01/26] KVM: arm64: Check advertised Stage-2 page size capability

2020-04-22 Thread Suzuki K Poulose

Hi Marc,

On 04/22/2020 01:00 PM, Marc Zyngier wrote:

With ARMv8.5-GTG, the hardware (or more likely a hypervisor) can
advertise the supported Stage-2 page sizes.

Let's check this at boot time.

Signed-off-by: Marc Zyngier 
---
  arch/arm64/include/asm/kvm_host.h |  2 +-
  arch/arm64/include/asm/sysreg.h   |  3 +++
  arch/arm64/kernel/cpufeature.c|  8 +++
  arch/arm64/kvm/reset.c| 40 ---
  virt/kvm/arm/arm.c|  4 +---
  5 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 32c8a675e5a4a..7dd8fefa6aecd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,7 +670,7 @@ static inline int kvm_arm_have_ssbd(void)
  void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
  void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
  
-void kvm_set_ipa_limit(void);

+int kvm_set_ipa_limit(void);
  
  #define __KVM_HAVE_ARCH_VM_ALLOC

  struct kvm *kvm_arch_alloc_vm(void);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ebc6224328318..5d10c9148e844 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -686,6 +686,9 @@
  #define ID_AA64ZFR0_SVEVER_SVE2   0x1
  
  /* id_aa64mmfr0 */

+#define ID_AA64MMFR0_TGRAN4_2_SHIFT40
+#define ID_AA64MMFR0_TGRAN64_2_SHIFT   36
+#define ID_AA64MMFR0_TGRAN16_2_SHIFT   32
  #define ID_AA64MMFR0_TGRAN4_SHIFT 28
  #define ID_AA64MMFR0_TGRAN64_SHIFT24
  #define ID_AA64MMFR0_TGRAN16_SHIFT20
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9fac745aa7bb2..9892a845d06c9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -208,6 +208,14 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
  };
  
  static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {

+   /*
+* Page size not being supported at Stage-2 are not fatal. You
+* just give up KVM if PAGE_SIZE isn't supported there. Go fix
+* your favourite nesting hypervisor.
+*/
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN4_2_SHIFT, 4, 1),
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN64_2_SHIFT, 4, 1),
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN16_2_SHIFT, 4, 1),


One minor issue with this is, if we get a system with cpus having values
0 and 2 (both of which indicates the stage-2 support), we might reset
the value to 1 for the feature indicating, we don't support and block
KVM. But, we can blame the nesting hypervisor for not emulating this to
(2). Do we need a comment to make this explicit here ?

Otherwise this looks fine to me

Suzuki




/*
 * We already refuse to boot CPUs that don't support our configured
 * page size, so we can only detect mismatches for a page size other
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 30b7ea680f66c..241db35a7ef4f 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -9,6 +9,7 @@
   */
  
  #include 

+#include 
  #include 
  #include 
  #include 
@@ -340,11 +341,42 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
return ret;
  }
  
-void kvm_set_ipa_limit(void)

+int kvm_set_ipa_limit(void)
  {
-   unsigned int ipa_max, pa_max, va_max, parange;
+   unsigned int ipa_max, pa_max, va_max, parange, tgran_2;
+   u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
  
-	parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 0x7;

+   /*
+* Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
+* Stage-2. If not, things will stop very quickly.
+*/
+   switch (PAGE_SIZE) {
+   default:
+   case SZ_4K:
+   tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT;
+   break;
+   case SZ_16K:
+   tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT;
+   break;
+   case SZ_64K:
+   tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT;
+   break;
+   }
+
+   switch (FIELD_GET(0xFUL << tgran_2, mmfr0)) {
+   default:
+   case 1:
+   kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
+   return -EINVAL;
+   case 0:
+   kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n");
+   break;
+   case 2:
+   kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n");
+   break;
+   }
+
+   parange = mmfr0 & 0x7;
pa_max = id_aa64mmfr0_parange_to_phys_shift(parange);
  
  	/* Clamp the IPA limit to the PA size supported by the kernel */

@@ -378,6 +410,8 @@ void kvm_set_ipa_limit(void)
 "KVM IPA limit (%d bit) is smaller than default size\n", ipa_max);
kvm_ipa_limit = ipa_max;
kvm_info("IPA Size Limit: %dbits\n", kvm_ipa_limit);
+
+  

[PATCH 01/26] KVM: arm64: Check advertised Stage-2 page size capability

2020-04-22 Thread Marc Zyngier
With ARMv8.5-GTG, the hardware (or more likely a hypervisor) can
advertise the supported Stage-2 page sizes.

Let's check this at boot time.

Signed-off-by: Marc Zyngier 
---
 arch/arm64/include/asm/kvm_host.h |  2 +-
 arch/arm64/include/asm/sysreg.h   |  3 +++
 arch/arm64/kernel/cpufeature.c|  8 +++
 arch/arm64/kvm/reset.c| 40 ---
 virt/kvm/arm/arm.c|  4 +---
 5 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 32c8a675e5a4a..7dd8fefa6aecd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,7 +670,7 @@ static inline int kvm_arm_have_ssbd(void)
 void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
 void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
 
-void kvm_set_ipa_limit(void);
+int kvm_set_ipa_limit(void);
 
 #define __KVM_HAVE_ARCH_VM_ALLOC
 struct kvm *kvm_arch_alloc_vm(void);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ebc6224328318..5d10c9148e844 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -686,6 +686,9 @@
 #define ID_AA64ZFR0_SVEVER_SVE20x1
 
 /* id_aa64mmfr0 */
+#define ID_AA64MMFR0_TGRAN4_2_SHIFT40
+#define ID_AA64MMFR0_TGRAN64_2_SHIFT   36
+#define ID_AA64MMFR0_TGRAN16_2_SHIFT   32
 #define ID_AA64MMFR0_TGRAN4_SHIFT  28
 #define ID_AA64MMFR0_TGRAN64_SHIFT 24
 #define ID_AA64MMFR0_TGRAN16_SHIFT 20
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9fac745aa7bb2..9892a845d06c9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -208,6 +208,14 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
+   /*
+* Page size not being supported at Stage-2 are not fatal. You
+* just give up KVM if PAGE_SIZE isn't supported there. Go fix
+* your favourite nesting hypervisor.
+*/
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN4_2_SHIFT, 4, 1),
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN64_2_SHIFT, 4, 1),
+   ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64MMFR0_TGRAN16_2_SHIFT, 4, 1),
/*
 * We already refuse to boot CPUs that don't support our configured
 * page size, so we can only detect mismatches for a page size other
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 30b7ea680f66c..241db35a7ef4f 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -9,6 +9,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -340,11 +341,42 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
return ret;
 }
 
-void kvm_set_ipa_limit(void)
+int kvm_set_ipa_limit(void)
 {
-   unsigned int ipa_max, pa_max, va_max, parange;
+   unsigned int ipa_max, pa_max, va_max, parange, tgran_2;
+   u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 
-   parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 0x7;
+   /*
+* Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
+* Stage-2. If not, things will stop very quickly.
+*/
+   switch (PAGE_SIZE) {
+   default:
+   case SZ_4K:
+   tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT;
+   break;
+   case SZ_16K:
+   tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT;
+   break;
+   case SZ_64K:
+   tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT;
+   break;
+   }
+
+   switch (FIELD_GET(0xFUL << tgran_2, mmfr0)) {
+   default:
+   case 1:
+   kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
+   return -EINVAL;
+   case 0:
+   kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n");
+   break;
+   case 2:
+   kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n");
+   break;
+   }
+
+   parange = mmfr0 & 0x7;
pa_max = id_aa64mmfr0_parange_to_phys_shift(parange);
 
/* Clamp the IPA limit to the PA size supported by the kernel */
@@ -378,6 +410,8 @@ void kvm_set_ipa_limit(void)
 "KVM IPA limit (%d bit) is smaller than default size\n", ipa_max);
kvm_ipa_limit = ipa_max;
kvm_info("IPA Size Limit: %dbits\n", kvm_ipa_limit);
+
+   return 0;
 }
 
 /*
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 48d0ec44ad77e..53b3ba9173ba7 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1387,9 +1387,7 @@ static inline void hyp_cpu_pm_exit(void)
 
 static int init_common_resources(void)
 {
-   kvm_set_ipa_limit();
-
-   return 0;
+   return kvm_set_ipa_limit();
 }
 
 static int init_subsystems(void)
-- 
2.26.1

___
kvmarm mail