[RFC PATCH part-6 02/13] pkvm: x86: init: Reserve memory for shadow EPT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx>

Shadow EPT pages are from the reserved memory of pKVM. The size for
Shadow EPT pages is calculated based on the number of supported VMs
(both normal VM and protected VM), with several assumptions:

- there is no shared memory between each VMs (normal or protected).
- all VMs total memory size is not larger than the platform memory size.
- the virtual MMIO range for each VM is not larger than 1G.

which makes the reserved memory size is calculable and predictable.

Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx>
Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx>
---
 arch/x86/include/asm/kvm_pkvm.h   | 34 +++++++++++++++++++++++++++++++
 arch/x86/kvm/vmx/pkvm/pkvm_host.c |  1 +
 2 files changed, 35 insertions(+)

diff --git a/arch/x86/include/asm/kvm_pkvm.h b/arch/x86/include/asm/kvm_pkvm.h
index 4e9531d88417..0712ef34b95b 100644
--- a/arch/x86/include/asm/kvm_pkvm.h
+++ b/arch/x86/include/asm/kvm_pkvm.h
@@ -131,6 +131,40 @@ static inline int hyp_pre_reserve_check(void)
 	return 0;
 }
 
+/*
+ * Calculate the total pages for shadow EPT with assumptions:
+ * 1. there is no shared memory between each VMs (normal or protected).
+ * 2. all VMs total memory size is no larger than the platform memory size.
+ * 3. the virtual MMIO range for each VM is no larger than 1G.
+ */
+static inline unsigned long pkvm_shadow_ept_pgtable_pages(int nr_vm)
+{
+	unsigned long pgtable_pages = __pkvm_pgtable_total_pages();
+	unsigned long res;
+
+	res = pgtable_pages;
+
+	/*
+	 * Above 'res' covered enough pages for a shadow EPT to create all
+	 * possible levels mapping for the whole platform memory size. The pages
+	 * reserved for lvl-1 mapping (usually 4K size) actually can be shared
+	 * among all VM shadow EPTs as their occupied memory are partitioned
+	 * according to the assumption. While for lvl-2,3,4 or possible lvl-5
+	 * mappings, above 'res' pages only covered for one shadow EPT, we need
+	 * reserve more for other 'nr_vm -1' VMs.
+	 *
+	 * The lvl-2 to lvl-5 pages for one VM's shadow EPT can be approximately
+	 * got by:
+	 *     __pkvm_pgtable_total_pages()/PTRS_PER_PTE
+	 */
+	res += DIV_ROUND_UP(pgtable_pages, PTRS_PER_PTE) * (nr_vm - 1);
+
+	/* Allow 1 GiB for MMIO mappings for each VM */
+	 res += __pkvm_pgtable_max_pages(SZ_1G >> PAGE_SHIFT) * nr_vm;
+
+	return res;
+}
+
 u64 hyp_total_reserve_pages(void);
 
 int pkvm_init_shadow_vm(struct kvm *kvm);
diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
index 90d7cddde9ef..e5eab94f3e5e 100644
--- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c
+++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
@@ -41,6 +41,7 @@ u64 hyp_total_reserve_pages(void)
 	total += pkvm_vmemmap_pages(PKVM_VMEMMAP_ENTRY_SIZE);
 	total += pkvm_mmu_pgtable_pages();
 	total += host_ept_pgtable_pages();
+	total += pkvm_shadow_ept_pgtable_pages(PKVM_MAX_VM_NUM);
 
 	return total;
 }
-- 
2.25.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux