ANDROID: KVM: arm64: Configure size of pKVM linear map on the cmdline

We currently reserve enough memory for pKVM to construct a stage-1
page-table that maps all of memory at page granularity. However, in
practice the amount of memory actually mapped into EL2 stage-1 is quite
small as it mainly consists of the hypervisor itself and guest metadata
(kvm, kvm_vcpu and related, plus stage-2 page-tables).

To avoid the waste, introduce a new kernel cmdline parameter that
defines how much memory can be mapped in total into the hypervisor
linear map at any point in time. This value should be set conservatively,
as allocation failures in the hypervisor are likely to be fatal.

Bug: 357781595
Bug: 239674049
Change-Id: I979fa07fa14566793f990d7e1ad9c8c3644cba9a
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
Quentin Perret
2025-01-30 13:35:41 +00:00
parent f3e6f2c64d
commit badb424ffc
4 changed files with 19 additions and 1 deletions
@@ -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.
+6 -1
View File
@@ -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);
+2
View File
@@ -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;
+6
View File
@@ -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;