@@ -343,6 +343,16 @@ static __always_inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vc
static __always_inline s8 kvm_vcpu_trap_get_fault_level(const struct kvm_vcpu *vcpu)
{
+ /*
+ * Note: With the introduction of FEAT_LPA2 an extra level of
+ * translation (level -1) is added. This level (obviously) doesn't
+ * follow the previous convention of encoding the 4 levels in the 2 LSBs
+ * of the FSC so this function breaks if the fault is for level -1.
+ *
+ * However, stage2 tables always use concatenated tables for first level
+ * lookup and therefore it is guaranteed that the level will be between
+ * 0 and 3, and this function continues to work.
+ */
return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC_LEVEL;
}
@@ -11,7 +11,7 @@
#include <linux/kvm_host.h>
#include <linux/types.h>
-#define KVM_PGTABLE_FIRST_LEVEL 0
+#define KVM_PGTABLE_FIRST_LEVEL -1
#define KVM_PGTABLE_LAST_LEVEL 3
/*
FEAT_LPA2 increases the maximum levels of translation from 4 to 5 for the 4KB page case, when IA is >48 bits. While we can still use 4 levels for stage2 translation in this case (due to stage2 allowing concatenated page tables for first level lookup), the same kvm_pgtable library is used for the hyp stage1 page tables and stage1 does not support concatenation. Therefore, modify the library to support upto 5 levels. Previous patches already laid the groundwork for this by refactoring code to work in terms of KVM_PGTABLE_FIRST_LEVEL and KVM_PGTABLE_LAST_LEVEL. So we just need to change these macros. The hardware sometimes encodes the new level differently from the others: One such place is when reading the level from the FSC field in the ESR_EL2 register. We never expect to see the lowest level (-1) here since the stage 2 page tables always use concatenated tables for first level lookup and therefore only use 4 levels of lookup. So we get away with just adding a comment to explain why we are not being careful about decoding level -1. Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> --- arch/arm64/include/asm/kvm_emulate.h | 10 ++++++++++ arch/arm64/include/asm/kvm_pgtable.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-)