diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 4a9aa64b2..273422ab1 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -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 diff --git a/hypervisor/arch/x86/page.c b/hypervisor/arch/x86/page.c index 75c981a34..6d8cb594c 100644 --- a/hypervisor/arch/x86/page.c +++ b/hypervisor/arch/x86/page.c @@ -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; + +} diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index 0898931b2..3a856e6fd 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -8,6 +8,7 @@ #define VM_H_ #include #include +#include #ifdef CONFIG_PARTITION_MODE #include @@ -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 */ diff --git a/hypervisor/include/arch/x86/page.h b/hypervisor/include/arch/x86/page.h index d49cfd4cf..838440523 100644 --- a/hypervisor/include/arch/x86/page.h +++ b/hypervisor/include/arch/x86/page.h @@ -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 */ diff --git a/hypervisor/include/arch/x86/trusty.h b/hypervisor/include/arch/x86/trusty.h index e51dc091f..20741fe47 100644 --- a/hypervisor/include/arch/x86/trusty.h +++ b/hypervisor/include/arch/x86/trusty.h @@ -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)