mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
[REVERT-ME]:handle discontinuous hpa for trusty
This is a temp solution to handle discontinuous hpa when create/destroy secure world ept. Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
This commit is contained in:
parent
5603afb2be
commit
a9d04cc5ce
@ -124,6 +124,7 @@ C_SRCS += arch/x86/vmexit.c
|
|||||||
C_SRCS += arch/x86/vmx.c
|
C_SRCS += arch/x86/vmx.c
|
||||||
C_SRCS += arch/x86/assign.c
|
C_SRCS += arch/x86/assign.c
|
||||||
C_SRCS += arch/x86/trusty.c
|
C_SRCS += arch/x86/trusty.c
|
||||||
|
C_SRCS += arch/x86/trusty2.c
|
||||||
C_SRCS += arch/x86/cpu_state_tbl.c
|
C_SRCS += arch/x86/cpu_state_tbl.c
|
||||||
C_SRCS += arch/x86/mtrr.c
|
C_SRCS += arch/x86/mtrr.c
|
||||||
C_SRCS += arch/x86/pm.c
|
C_SRCS += arch/x86/pm.c
|
||||||
|
@ -50,6 +50,8 @@ static struct key_info g_key_info = {
|
|||||||
exec_vmwrite(VMX_GUEST_##SEG_NAME##_ATTR, seg.attr); \
|
exec_vmwrite(VMX_GUEST_##SEG_NAME##_ATTR, seg.attr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WORKAROUND_FOR_TRUSTY_4G_MEM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup trusty_apis Trusty APIs
|
* @defgroup trusty_apis Trusty APIs
|
||||||
*
|
*
|
||||||
@ -209,6 +211,7 @@ void destroy_secure_world(struct vm *vm)
|
|||||||
IA32E_EPT_WB));
|
IA32E_EPT_WB));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void save_world_ctx(struct run_context *context)
|
static void save_world_ctx(struct run_context *context)
|
||||||
{
|
{
|
||||||
|
223
hypervisor/arch/x86/trusty2.c
Normal file
223
hypervisor/arch/x86/trusty2.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hypervisor.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WORKAROUND_FOR_TRUSTY_4G_MEM
|
||||||
|
|
||||||
|
uint64_t gpa2hpa_for_trusty(struct vm *vm, uint64_t gpa)
|
||||||
|
{
|
||||||
|
uint64_t hpa = 0UL;
|
||||||
|
struct entry_params entry;
|
||||||
|
struct map_params map_params;
|
||||||
|
|
||||||
|
map_params.page_table_type = PTT_EPT;
|
||||||
|
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
|
||||||
|
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
|
||||||
|
obtain_last_page_table_entry(&map_params, &entry, (void *)gpa, true);
|
||||||
|
if (entry.entry_present == PT_PRESENT) {
|
||||||
|
hpa = ((entry.entry_val & (~(entry.page_size - 1UL)))
|
||||||
|
| (gpa & (entry.page_size - 1UL)));
|
||||||
|
pr_dbg("GPA2HPA: 0x%llx->0x%llx", gpa, hpa);
|
||||||
|
} else {
|
||||||
|
pr_err("VM %d GPA2HPA: failed for gpa 0x%llx",
|
||||||
|
vm->attr.boot_idx, gpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hpa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup trusty_apis Trusty APIs
|
||||||
|
*
|
||||||
|
* This is a special group that includes all APIs
|
||||||
|
* related to Trusty
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create Secure World EPT hierarchy
|
||||||
|
*
|
||||||
|
* Create Secure World EPT hierarchy, construct new PML4/PDPT,
|
||||||
|
* reuse PD/PT parse from vm->arch_vm->ept
|
||||||
|
*
|
||||||
|
* @param vm pointer to a VM with 2 Worlds
|
||||||
|
* @param gpa_orig original gpa allocated from vSBL
|
||||||
|
* @param size LK size (16M by default)
|
||||||
|
* @param gpa_rebased gpa rebased to offset xxx (511G_OFFSET)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
|
||||||
|
int64_t size, uint64_t gpa_rebased)
|
||||||
|
{
|
||||||
|
uint64_t nworld_pml4e = 0UL;
|
||||||
|
uint64_t sworld_pml4e = 0UL;
|
||||||
|
struct entry_params entry;
|
||||||
|
struct map_params map_params;
|
||||||
|
uint64_t gpa_uos = gpa_orig;
|
||||||
|
uint64_t gpa_sos;
|
||||||
|
uint64_t adjust_size;
|
||||||
|
uint64_t mod;
|
||||||
|
uint64_t hpa = gpa2hpa(vm, gpa_uos);
|
||||||
|
void *sub_table_addr = NULL, *pml4_base = NULL;
|
||||||
|
int i;
|
||||||
|
struct vm *vm0 = get_vm_from_vmid(0);
|
||||||
|
struct vcpu *vcpu;
|
||||||
|
|
||||||
|
if (vm0 == NULL) {
|
||||||
|
pr_err("Parse vm0 context failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vm->sworld_control.sworld_enabled
|
||||||
|
|| vm->arch_vm.sworld_eptp != 0UL) {
|
||||||
|
pr_err("Sworld is not enabled or Sworld eptp is not NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backup secure world info, will be used when
|
||||||
|
* destroy secure world
|
||||||
|
*/
|
||||||
|
vm->sworld_control.sworld_memory.base_gpa = gpa_rebased;
|
||||||
|
vm->sworld_control.sworld_memory.base_hpa = hpa;
|
||||||
|
vm->sworld_control.sworld_memory.length = (uint64_t)size;
|
||||||
|
vm->sworld_control.sworld_memory.gpa_sos = hpa2gpa(vm0, hpa);
|
||||||
|
vm->sworld_control.sworld_memory.gpa_uos = gpa_orig;
|
||||||
|
|
||||||
|
/* Copy PDPT entries from Normal world to Secure world
|
||||||
|
* Secure world can access Normal World's memory,
|
||||||
|
* but Normal World can not access Secure World's memory.
|
||||||
|
* The PML4/PDPT for Secure world are separated from
|
||||||
|
* Normal World.PD/PT are shared in both Secure world's EPT
|
||||||
|
* and Normal World's EPT
|
||||||
|
*/
|
||||||
|
pml4_base = alloc_paging_struct();
|
||||||
|
vm->arch_vm.sworld_eptp = HVA2HPA(pml4_base);
|
||||||
|
|
||||||
|
/* The trusty memory is remapped to guest physical address
|
||||||
|
* of gpa_rebased to gpa_rebased + size
|
||||||
|
*/
|
||||||
|
sub_table_addr = alloc_paging_struct();
|
||||||
|
sworld_pml4e = HVA2HPA(sub_table_addr) | IA32E_EPT_R_BIT |
|
||||||
|
IA32E_EPT_W_BIT |
|
||||||
|
IA32E_EPT_X_BIT;
|
||||||
|
mem_write64(pml4_base, sworld_pml4e);
|
||||||
|
|
||||||
|
nworld_pml4e = mem_read64(HPA2HVA(vm->arch_vm.nworld_eptp));
|
||||||
|
(void)memcpy_s(HPA2HVA(sworld_pml4e & IA32E_REF_MASK), CPU_PAGE_SIZE,
|
||||||
|
HPA2HVA(nworld_pml4e & IA32E_REF_MASK), CPU_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Unmap gpa_orig~gpa_orig+size from guest normal world ept mapping */
|
||||||
|
map_params.page_table_type = PTT_EPT;
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
|
map_params.pml4_base = HPA2HVA(vm->arch_vm.nworld_eptp);
|
||||||
|
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
|
||||||
|
obtain_last_page_table_entry(&map_params, &entry,
|
||||||
|
(void *)gpa_uos, true);
|
||||||
|
mod = (gpa_uos % entry.page_size);
|
||||||
|
adjust_size = (mod) ? (entry.page_size - mod) : entry.page_size;
|
||||||
|
if ((uint64_t)size < entry.page_size)
|
||||||
|
adjust_size = size;
|
||||||
|
hpa = gpa2hpa(vm, gpa_uos);
|
||||||
|
|
||||||
|
/* Unmap from normal world */
|
||||||
|
unmap_mem(&map_params, (void *)hpa,
|
||||||
|
(void *)gpa_uos, adjust_size, 0U);
|
||||||
|
|
||||||
|
/* Map to secure world */
|
||||||
|
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
|
||||||
|
map_mem(&map_params, (void *)hpa,
|
||||||
|
(void *)gpa_rebased, adjust_size,
|
||||||
|
(IA32E_EPT_R_BIT |
|
||||||
|
IA32E_EPT_W_BIT |
|
||||||
|
IA32E_EPT_X_BIT |
|
||||||
|
IA32E_EPT_WB));
|
||||||
|
|
||||||
|
/* Unmap trusty memory space from sos ept mapping*/
|
||||||
|
map_params.pml4_base = HPA2HVA(vm0->arch_vm.nworld_eptp);
|
||||||
|
map_params.pml4_inverted = HPA2HVA(vm0->arch_vm.m2p);
|
||||||
|
/* Get the gpa address in SOS */
|
||||||
|
gpa_sos = hpa2gpa(vm0, hpa);
|
||||||
|
|
||||||
|
unmap_mem(&map_params, (void *)hpa,
|
||||||
|
(void *)gpa_sos, adjust_size, 0U);
|
||||||
|
gpa_uos += adjust_size;
|
||||||
|
size -= adjust_size;
|
||||||
|
gpa_rebased += adjust_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_vcpu(i, vm, vcpu) {
|
||||||
|
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_vcpu(i, vm0, vcpu) {
|
||||||
|
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_secure_world(struct vm *vm)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct map_params map_params;
|
||||||
|
struct entry_params entry;
|
||||||
|
struct vm *vm0 = get_vm_from_vmid(0);
|
||||||
|
uint64_t hpa;
|
||||||
|
uint64_t mod;
|
||||||
|
int i;
|
||||||
|
struct vcpu *vcpu;
|
||||||
|
uint64_t adjust_size;
|
||||||
|
uint64_t gpa = vm->sworld_control.sworld_memory.base_gpa;
|
||||||
|
int64_t size = (int64_t)vm->sworld_control.sworld_memory.length;
|
||||||
|
|
||||||
|
if (vm0 == NULL) {
|
||||||
|
pr_err("Parse vm0 context failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_params.page_table_type = PTT_EPT;
|
||||||
|
while (size > 0) {
|
||||||
|
/* clear trusty memory space */
|
||||||
|
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
|
||||||
|
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
|
||||||
|
obtain_last_page_table_entry(&map_params, &entry,
|
||||||
|
(void *)gpa, true);
|
||||||
|
hpa = gpa2hpa_for_trusty(vm, gpa);
|
||||||
|
mod = (hpa % entry.page_size);
|
||||||
|
adjust_size = (mod) ? (entry.page_size - mod) : entry.page_size;
|
||||||
|
if ((uint64_t)size < entry.page_size)
|
||||||
|
adjust_size = size;
|
||||||
|
|
||||||
|
(void)memset(HPA2HVA(hpa), 0, adjust_size);
|
||||||
|
/* restore memory to SOS ept mapping */
|
||||||
|
map_params.pml4_base = HPA2HVA(vm0->arch_vm.nworld_eptp);
|
||||||
|
map_params.pml4_inverted = HPA2HVA(vm0->arch_vm.m2p);
|
||||||
|
/* here gpa=hpa because sos 1:1 mapping
|
||||||
|
* this is a temp solution
|
||||||
|
*/
|
||||||
|
map_mem(&map_params, (void *)hpa,
|
||||||
|
(void *)hpa,
|
||||||
|
adjust_size,
|
||||||
|
(IA32E_EPT_R_BIT |
|
||||||
|
IA32E_EPT_W_BIT |
|
||||||
|
IA32E_EPT_X_BIT |
|
||||||
|
IA32E_EPT_WB));
|
||||||
|
size -= adjust_size;
|
||||||
|
gpa += adjust_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_vcpu(i, vm, vcpu) {
|
||||||
|
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_vcpu(i, vm0, vcpu) {
|
||||||
|
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -7,7 +7,11 @@
|
|||||||
#ifndef TRUSTY_H_
|
#ifndef TRUSTY_H_
|
||||||
#define TRUSTY_H_
|
#define TRUSTY_H_
|
||||||
|
|
||||||
|
/* This is a temp solution for 4GB memory */
|
||||||
|
#define WORKAROUND_FOR_TRUSTY_4G_MEM
|
||||||
|
|
||||||
#define BOOTLOADER_SEED_MAX_ENTRIES 10U
|
#define BOOTLOADER_SEED_MAX_ENTRIES 10U
|
||||||
|
|
||||||
#define RPMB_MAX_PARTITION_NUMBER 6
|
#define RPMB_MAX_PARTITION_NUMBER 6
|
||||||
#define MMC_PROD_NAME_WITH_PSN_LEN 15
|
#define MMC_PROD_NAME_WITH_PSN_LEN 15
|
||||||
#define BUP_MKHI_BOOTLOADER_SEED_LEN 64
|
#define BUP_MKHI_BOOTLOADER_SEED_LEN 64
|
||||||
@ -90,6 +94,23 @@ struct key_info {
|
|||||||
char pad2;
|
char pad2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef WORKAROUND_FOR_TRUSTY_4G_MEM
|
||||||
|
void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
|
||||||
|
int64_t size, uint64_t gpa_rebased);
|
||||||
|
struct secure_world_memory {
|
||||||
|
/* The secure world base address of GPA for secure world*/
|
||||||
|
uint64_t base_gpa;
|
||||||
|
/* The secure world base address of HPA */
|
||||||
|
uint64_t base_hpa;
|
||||||
|
/* Secure world runtime memory size */
|
||||||
|
uint64_t length;
|
||||||
|
/* The secure world base address of GPA in SOS */
|
||||||
|
uint64_t gpa_sos;
|
||||||
|
/* The secure world base address of GPA in UOS for normal world */
|
||||||
|
uint64_t gpa_uos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
struct secure_world_memory {
|
struct secure_world_memory {
|
||||||
/* The secure world base address of GPA in SOS */
|
/* The secure world base address of GPA in SOS */
|
||||||
uint64_t base_gpa;
|
uint64_t base_gpa;
|
||||||
@ -98,6 +119,7 @@ struct secure_world_memory {
|
|||||||
/* Secure world runtime memory size */
|
/* Secure world runtime memory size */
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct secure_world_control {
|
struct secure_world_control {
|
||||||
/* Whether secure world is enabled for current VM */
|
/* Whether secure world is enabled for current VM */
|
||||||
|
Loading…
Reference in New Issue
Block a user