hv: mmu: add static paging table allocation for EPT

Add static paging table allocation API for EPT.
Note: must configure SOS/UOS_REAM_SIZE exactly as the platform.

Tracked-On: #861
Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2018-11-02 02:25:15 +08:00 committed by lijinxia
parent dc9d18a868
commit 9c7c0de08f
5 changed files with 141 additions and 0 deletions

View File

@ -235,6 +235,21 @@ config PLATFORM_RAM_SIZE
A 64-bit integer indicating the size of the physical platform RAM
(not included the MMIO).
config SOS_RAM_SIZE
hex "Size of the vm0 RAM"
default 0x200000000 if SHARING_MODE
default 0x000000000 if PARTITION_MODE
help
A 64-bit integer indicating the size of the vm0 RAM (not included the MMIO).
config UOS_RAM_SIZE
hex "Size of the UOS RAM"
default 0x100000000 if SHARING_MODE
default 0x100000000 if PARTITION_MODE
help
A 64-bit integer indicating the size of the user OS RAM (not included the MMIO).
Now we assume each UOS uses same amount of RAM size.
config CONSTANT_ACPI
bool "The platform ACPI info is constant"
default n

View File

@ -65,3 +65,122 @@ const struct memory_ops ppt_mem_ops = {
.get_pdpt_page = ppt_get_pdpt_page,
.get_pd_page = ppt_get_pd_page,
};
/* The size of the guest physical address space, covered by the EPT page table of a VM */
#define EPT_ADDRESS_SPACE(size) ((size != 0UL) ? (size + PLATFORM_LO_MMIO_SIZE) : 0UL)
DEFINE_PGTABLE_PAGE(vm0_, pml4, PML4, EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE));
DEFINE_PGTABLE_PAGE(vm0_, pdpt, PDPT, EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE));
DEFINE_PGTABLE_PAGE(vm0_, pd, PD, EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE));
DEFINE_PGTABLE_PAGE(vm0_, pt, PT, EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE));
/* uos_nworld_pml4_pages[i] is ...... of UOS i (whose vm_id = i +1) */
static struct page uos_nworld_pml4_pages[CONFIG_MAX_VM_NUM - 1U][PML4_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE))];
static struct page uos_nworld_pdpt_pages[CONFIG_MAX_VM_NUM - 1U][PDPT_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE))];
static struct page uos_nworld_pd_pages[CONFIG_MAX_VM_NUM - 1U][PD_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE))];
static struct page uos_nworld_pt_pages[CONFIG_MAX_VM_NUM - 1U][PT_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE))];
#define TRUSTY_PML4_PAGE_NUM(size) (1UL)
#define TRUSTY_PDPT_PAGE_NUM(size) (1UL)
#define TRUSTY_PD_PAGE_NUM(size) (PD_PAGE_NUM(size))
#define TRUSTY_PT_PAGE_NUM(size) (PT_PAGE_NUM(size))
#define TRUSTY_PGTABLE_PAGE_NUM(size) \
(TRUSTY_PML4_PAGE_NUM(size) + TRUSTY_PDPT_PAGE_NUM(size) + TRUSTY_PD_PAGE_NUM(size) + TRUSTY_PT_PAGE_NUM(size))
static struct page uos_sworld_pgtable_pages[CONFIG_MAX_VM_NUM - 1U][TRUSTY_PGTABLE_PAGE_NUM(TRUSTY_RAM_SIZE)];
/* ept: extended page table*/
static union pgtable_pages_info ept_pages_info[CONFIG_MAX_VM_NUM] = {
{
.ept = {
.top_address_space = EPT_ADDRESS_SPACE(CONFIG_SOS_RAM_SIZE),
.nworld_pml4_base = vm0_pml4_pages,
.nworld_pdpt_base = vm0_pdpt_pages,
.nworld_pd_base = vm0_pd_pages,
.nworld_pt_base = vm0_pt_pages,
},
},
};
static inline uint64_t ept_get_default_access_right(void)
{
return EPT_RWX;
}
static inline uint64_t ept_pgentry_present(uint64_t pte)
{
return pte & EPT_RWX;
}
static inline struct page *ept_get_pml4_page(const union pgtable_pages_info *info, __unused uint64_t gpa)
{
struct page *page;
if (gpa < TRUSTY_EPT_REBASE_GPA) {
page = info->ept.nworld_pml4_base;
} else {
page = info->ept.sworld_pgtable_base;
}
(void)memset(page, 0U, PAGE_SIZE);
return page;
}
static inline struct page *ept_get_pdpt_page(const union pgtable_pages_info *info, uint64_t gpa)
{
struct page *page;
if (gpa < TRUSTY_EPT_REBASE_GPA) {
page = info->ept.nworld_pdpt_base + (gpa >> PML4E_SHIFT);
} else {
page = info->ept.sworld_pgtable_base + TRUSTY_PML4_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) +
((gpa - TRUSTY_EPT_REBASE_GPA) >> PML4E_SHIFT);
}
(void)memset(page, 0U, PAGE_SIZE);
return page;
}
static inline struct page *ept_get_pd_page(const union pgtable_pages_info *info, uint64_t gpa)
{
struct page *page;
if (gpa < TRUSTY_EPT_REBASE_GPA) {
page = info->ept.nworld_pd_base + (gpa >> PDPTE_SHIFT);
} else {
page = info->ept.sworld_pgtable_base + TRUSTY_PML4_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) +
TRUSTY_PDPT_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) + ((gpa - TRUSTY_EPT_REBASE_GPA) >> PDPTE_SHIFT);
}
(void)memset(page, 0U, PAGE_SIZE);
return page;
}
static inline struct page *ept_get_pt_page(const union pgtable_pages_info *info, uint64_t gpa)
{
struct page *page;
if (gpa < TRUSTY_EPT_REBASE_GPA) {
page = info->ept.nworld_pt_base + (gpa >> PDE_SHIFT);
} else {
page = info->ept.sworld_pgtable_base + TRUSTY_PML4_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) +
TRUSTY_PDPT_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) + TRUSTY_PD_PAGE_NUM(TRUSTY_EPT_REBASE_GPA) +
((gpa - TRUSTY_EPT_REBASE_GPA) >> PDE_SHIFT);
}
(void)memset(page, 0U, PAGE_SIZE);
return page;
}
void init_ept_mem_ops(struct vm *vm)
{
uint16_t vm_id = vm->vm_id;
if (vm_id != 0U) {
ept_pages_info[vm_id].ept.top_address_space = EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE);
ept_pages_info[vm_id].ept.nworld_pml4_base = uos_nworld_pml4_pages[vm_id - 1U];
ept_pages_info[vm_id].ept.nworld_pdpt_base = uos_nworld_pdpt_pages[vm_id - 1U];
ept_pages_info[vm_id].ept.nworld_pd_base = uos_nworld_pd_pages[vm_id - 1U];
ept_pages_info[vm_id].ept.nworld_pt_base = uos_nworld_pt_pages[vm_id - 1U];
ept_pages_info[vm_id].ept.sworld_pgtable_base = uos_sworld_pgtable_pages[vm_id - 1U];
}
vm->arch_vm.ept_mem_ops.info = &ept_pages_info[vm_id];
vm->arch_vm.ept_mem_ops.get_default_access_right = ept_get_default_access_right;
vm->arch_vm.ept_mem_ops.pgentry_present = ept_pgentry_present;
vm->arch_vm.ept_mem_ops.get_pml4_page = ept_get_pml4_page;
vm->arch_vm.ept_mem_ops.get_pdpt_page = ept_get_pdpt_page;
vm->arch_vm.ept_mem_ops.get_pd_page = ept_get_pd_page;
vm->arch_vm.ept_mem_ops.get_pt_page = ept_get_pt_page;
}

View File

@ -8,6 +8,7 @@
#define VM_H_
#include <bsp_extern.h>
#include <vpci.h>
#include <page.h>
#ifdef CONFIG_PARTITION_MODE
#include <mptable.h>
@ -97,6 +98,8 @@ struct vm_arch {
* but Normal World can not access Secure World's memory.
*/
void *sworld_eptp;
struct memory_ops ept_mem_ops;
void *tmp_pg_array; /* Page array for tmp guest paging struct */
struct acrn_vioapic vioapic; /* Virtual IOAPIC base address */
struct acrn_vpic vpic; /* Virtual PIC */

View File

@ -25,6 +25,7 @@ union pgtable_pages_info {
struct page *pt_base;
} ppt;
struct {
uint64_t top_address_space;
struct page *nworld_pml4_base;
struct page *nworld_pdpt_base;
struct page *nworld_pd_base;
@ -44,5 +45,6 @@ struct memory_ops {
};
extern const struct memory_ops ppt_mem_ops;
void init_ept_mem_ops(struct vm *vm);
#endif /* PAGE_H */

View File

@ -12,6 +12,8 @@
#define MMC_PROD_NAME_WITH_PSN_LEN 15U
#define BUP_MKHI_BOOTLOADER_SEED_LEN 64U
#define TRUSTY_RAM_SIZE (16UL * 1024UL * 1024UL) /* 16 MB for now */
/* Trusty EPT rebase gpa: 511G */
#define TRUSTY_EPT_REBASE_GPA (511UL * 1024UL * 1024UL * 1024UL)