diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 87b78abce5c6..dface3efc74f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2739,6 +2739,11 @@ (enabled). Disable by KVM if hardware lacks support for NPT. + kvm-arm.hyp_lm_size_mb= + [KVM,ARM,EARLY] Maximum amount of contiguous memory mappable in + the pKVM hypervisor linear map, in MB. Any attempt to map more + memory than this into pKVM stage-1 at run-time may be fatal. + kvm-arm.mode= [KVM,ARM,EARLY] Select one of KVM/arm64's modes of operation. diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index 31b22c3f02df..3711d47f6c04 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -345,11 +345,16 @@ static inline unsigned long __hyp_pgtable_moveable_regs_pages(void) return res; } +extern u64 kvm_nvhe_sym(hyp_lm_size_mb); + static inline unsigned long hyp_s1_pgtable_pages(void) { unsigned long res; - res = __hyp_pgtable_moveable_regs_pages(); + if (!kvm_nvhe_sym(hyp_lm_size_mb)) + res = __hyp_pgtable_moveable_regs_pages(); + else + res = __hyp_pgtable_max_pages(kvm_nvhe_sym(hyp_lm_size_mb) * SZ_1M / PAGE_SIZE); /* Allow 1 GiB for private mappings */ res += __hyp_pgtable_max_pages(SZ_1G >> PAGE_SHIFT); diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index ae16d88cb30b..362eedfd52d8 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -30,6 +30,8 @@ phys_addr_t pvmfw_size; #define hyp_percpu_size ((unsigned long)__per_cpu_end - \ (unsigned long)__per_cpu_start) +u64 hyp_lm_size_mb; + static void *vmemmap_base; static void *vm_table_base; static void *hyp_pgt_base; diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 3c3bb7bde3d5..3f4cd545e8b1 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -185,6 +185,12 @@ out_fail: return ret; } +static int __init early_hyp_lm_size_mb_cfg(char *arg) +{ + return kstrtoull(arg, 10, &kvm_nvhe_sym(hyp_lm_size_mb)); +} +early_param("kvm-arm.hyp_lm_size_mb", early_hyp_lm_size_mb_cfg); + void __init kvm_hyp_reserve(void) { u64 hyp_mem_pages = 0;