Skip to content

Commit a9d04cc

Browse files
mingqiangchilijinxia
authored andcommitted
[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>
1 parent 5603afb commit a9d04cc

File tree

4 files changed

+249
-0
lines changed

4 files changed

+249
-0
lines changed

hypervisor/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ C_SRCS += arch/x86/vmexit.c
124124
C_SRCS += arch/x86/vmx.c
125125
C_SRCS += arch/x86/assign.c
126126
C_SRCS += arch/x86/trusty.c
127+
C_SRCS += arch/x86/trusty2.c
127128
C_SRCS += arch/x86/cpu_state_tbl.c
128129
C_SRCS += arch/x86/mtrr.c
129130
C_SRCS += arch/x86/pm.c

hypervisor/arch/x86/trusty.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ static struct key_info g_key_info = {
5050
exec_vmwrite(VMX_GUEST_##SEG_NAME##_ATTR, seg.attr); \
5151
}
5252

53+
#ifndef WORKAROUND_FOR_TRUSTY_4G_MEM
54+
5355
/**
5456
* @defgroup trusty_apis Trusty APIs
5557
*
@@ -209,6 +211,7 @@ void destroy_secure_world(struct vm *vm)
209211
IA32E_EPT_WB));
210212

211213
}
214+
#endif
212215

213216
static void save_world_ctx(struct run_context *context)
214217
{

hypervisor/arch/x86/trusty2.c

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include <hypervisor.h>
8+
9+
10+
#ifdef WORKAROUND_FOR_TRUSTY_4G_MEM
11+
12+
uint64_t gpa2hpa_for_trusty(struct vm *vm, uint64_t gpa)
13+
{
14+
uint64_t hpa = 0UL;
15+
struct entry_params entry;
16+
struct map_params map_params;
17+
18+
map_params.page_table_type = PTT_EPT;
19+
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
20+
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
21+
obtain_last_page_table_entry(&map_params, &entry, (void *)gpa, true);
22+
if (entry.entry_present == PT_PRESENT) {
23+
hpa = ((entry.entry_val & (~(entry.page_size - 1UL)))
24+
| (gpa & (entry.page_size - 1UL)));
25+
pr_dbg("GPA2HPA: 0x%llx->0x%llx", gpa, hpa);
26+
} else {
27+
pr_err("VM %d GPA2HPA: failed for gpa 0x%llx",
28+
vm->attr.boot_idx, gpa);
29+
}
30+
31+
return hpa;
32+
}
33+
34+
/**
35+
* @defgroup trusty_apis Trusty APIs
36+
*
37+
* This is a special group that includes all APIs
38+
* related to Trusty
39+
*
40+
* @{
41+
*/
42+
43+
/**
44+
* @brief Create Secure World EPT hierarchy
45+
*
46+
* Create Secure World EPT hierarchy, construct new PML4/PDPT,
47+
* reuse PD/PT parse from vm->arch_vm->ept
48+
*
49+
* @param vm pointer to a VM with 2 Worlds
50+
* @param gpa_orig original gpa allocated from vSBL
51+
* @param size LK size (16M by default)
52+
* @param gpa_rebased gpa rebased to offset xxx (511G_OFFSET)
53+
*
54+
*/
55+
void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
56+
int64_t size, uint64_t gpa_rebased)
57+
{
58+
uint64_t nworld_pml4e = 0UL;
59+
uint64_t sworld_pml4e = 0UL;
60+
struct entry_params entry;
61+
struct map_params map_params;
62+
uint64_t gpa_uos = gpa_orig;
63+
uint64_t gpa_sos;
64+
uint64_t adjust_size;
65+
uint64_t mod;
66+
uint64_t hpa = gpa2hpa(vm, gpa_uos);
67+
void *sub_table_addr = NULL, *pml4_base = NULL;
68+
int i;
69+
struct vm *vm0 = get_vm_from_vmid(0);
70+
struct vcpu *vcpu;
71+
72+
if (vm0 == NULL) {
73+
pr_err("Parse vm0 context failed.");
74+
return;
75+
}
76+
77+
if (!vm->sworld_control.sworld_enabled
78+
|| vm->arch_vm.sworld_eptp != 0UL) {
79+
pr_err("Sworld is not enabled or Sworld eptp is not NULL");
80+
return;
81+
}
82+
83+
/* Backup secure world info, will be used when
84+
* destroy secure world
85+
*/
86+
vm->sworld_control.sworld_memory.base_gpa = gpa_rebased;
87+
vm->sworld_control.sworld_memory.base_hpa = hpa;
88+
vm->sworld_control.sworld_memory.length = (uint64_t)size;
89+
vm->sworld_control.sworld_memory.gpa_sos = hpa2gpa(vm0, hpa);
90+
vm->sworld_control.sworld_memory.gpa_uos = gpa_orig;
91+
92+
/* Copy PDPT entries from Normal world to Secure world
93+
* Secure world can access Normal World's memory,
94+
* but Normal World can not access Secure World's memory.
95+
* The PML4/PDPT for Secure world are separated from
96+
* Normal World.PD/PT are shared in both Secure world's EPT
97+
* and Normal World's EPT
98+
*/
99+
pml4_base = alloc_paging_struct();
100+
vm->arch_vm.sworld_eptp = HVA2HPA(pml4_base);
101+
102+
/* The trusty memory is remapped to guest physical address
103+
* of gpa_rebased to gpa_rebased + size
104+
*/
105+
sub_table_addr = alloc_paging_struct();
106+
sworld_pml4e = HVA2HPA(sub_table_addr) | IA32E_EPT_R_BIT |
107+
IA32E_EPT_W_BIT |
108+
IA32E_EPT_X_BIT;
109+
mem_write64(pml4_base, sworld_pml4e);
110+
111+
nworld_pml4e = mem_read64(HPA2HVA(vm->arch_vm.nworld_eptp));
112+
(void)memcpy_s(HPA2HVA(sworld_pml4e & IA32E_REF_MASK), CPU_PAGE_SIZE,
113+
HPA2HVA(nworld_pml4e & IA32E_REF_MASK), CPU_PAGE_SIZE);
114+
115+
/* Unmap gpa_orig~gpa_orig+size from guest normal world ept mapping */
116+
map_params.page_table_type = PTT_EPT;
117+
118+
while (size > 0) {
119+
map_params.pml4_base = HPA2HVA(vm->arch_vm.nworld_eptp);
120+
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
121+
obtain_last_page_table_entry(&map_params, &entry,
122+
(void *)gpa_uos, true);
123+
mod = (gpa_uos % entry.page_size);
124+
adjust_size = (mod) ? (entry.page_size - mod) : entry.page_size;
125+
if ((uint64_t)size < entry.page_size)
126+
adjust_size = size;
127+
hpa = gpa2hpa(vm, gpa_uos);
128+
129+
/* Unmap from normal world */
130+
unmap_mem(&map_params, (void *)hpa,
131+
(void *)gpa_uos, adjust_size, 0U);
132+
133+
/* Map to secure world */
134+
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
135+
map_mem(&map_params, (void *)hpa,
136+
(void *)gpa_rebased, adjust_size,
137+
(IA32E_EPT_R_BIT |
138+
IA32E_EPT_W_BIT |
139+
IA32E_EPT_X_BIT |
140+
IA32E_EPT_WB));
141+
142+
/* Unmap trusty memory space from sos ept mapping*/
143+
map_params.pml4_base = HPA2HVA(vm0->arch_vm.nworld_eptp);
144+
map_params.pml4_inverted = HPA2HVA(vm0->arch_vm.m2p);
145+
/* Get the gpa address in SOS */
146+
gpa_sos = hpa2gpa(vm0, hpa);
147+
148+
unmap_mem(&map_params, (void *)hpa,
149+
(void *)gpa_sos, adjust_size, 0U);
150+
gpa_uos += adjust_size;
151+
size -= adjust_size;
152+
gpa_rebased += adjust_size;
153+
}
154+
155+
foreach_vcpu(i, vm, vcpu) {
156+
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
157+
}
158+
159+
foreach_vcpu(i, vm0, vcpu) {
160+
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
161+
}
162+
}
163+
164+
void destroy_secure_world(struct vm *vm)
165+
{
166+
167+
struct map_params map_params;
168+
struct entry_params entry;
169+
struct vm *vm0 = get_vm_from_vmid(0);
170+
uint64_t hpa;
171+
uint64_t mod;
172+
int i;
173+
struct vcpu *vcpu;
174+
uint64_t adjust_size;
175+
uint64_t gpa = vm->sworld_control.sworld_memory.base_gpa;
176+
int64_t size = (int64_t)vm->sworld_control.sworld_memory.length;
177+
178+
if (vm0 == NULL) {
179+
pr_err("Parse vm0 context failed.");
180+
return;
181+
}
182+
183+
map_params.page_table_type = PTT_EPT;
184+
while (size > 0) {
185+
/* clear trusty memory space */
186+
map_params.pml4_base = HPA2HVA(vm->arch_vm.sworld_eptp);
187+
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
188+
obtain_last_page_table_entry(&map_params, &entry,
189+
(void *)gpa, true);
190+
hpa = gpa2hpa_for_trusty(vm, gpa);
191+
mod = (hpa % entry.page_size);
192+
adjust_size = (mod) ? (entry.page_size - mod) : entry.page_size;
193+
if ((uint64_t)size < entry.page_size)
194+
adjust_size = size;
195+
196+
(void)memset(HPA2HVA(hpa), 0, adjust_size);
197+
/* restore memory to SOS ept mapping */
198+
map_params.pml4_base = HPA2HVA(vm0->arch_vm.nworld_eptp);
199+
map_params.pml4_inverted = HPA2HVA(vm0->arch_vm.m2p);
200+
/* here gpa=hpa because sos 1:1 mapping
201+
* this is a temp solution
202+
*/
203+
map_mem(&map_params, (void *)hpa,
204+
(void *)hpa,
205+
adjust_size,
206+
(IA32E_EPT_R_BIT |
207+
IA32E_EPT_W_BIT |
208+
IA32E_EPT_X_BIT |
209+
IA32E_EPT_WB));
210+
size -= adjust_size;
211+
gpa += adjust_size;
212+
213+
}
214+
215+
foreach_vcpu(i, vm, vcpu) {
216+
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
217+
}
218+
219+
foreach_vcpu(i, vm0, vcpu) {
220+
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
221+
}
222+
}
223+
#endif

hypervisor/include/arch/x86/trusty.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
#ifndef TRUSTY_H_
88
#define TRUSTY_H_
99

10+
/* This is a temp solution for 4GB memory */
11+
#define WORKAROUND_FOR_TRUSTY_4G_MEM
12+
1013
#define BOOTLOADER_SEED_MAX_ENTRIES 10U
14+
1115
#define RPMB_MAX_PARTITION_NUMBER 6
1216
#define MMC_PROD_NAME_WITH_PSN_LEN 15
1317
#define BUP_MKHI_BOOTLOADER_SEED_LEN 64
@@ -90,6 +94,23 @@ struct key_info {
9094
char pad2;
9195
};
9296

97+
#ifdef WORKAROUND_FOR_TRUSTY_4G_MEM
98+
void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
99+
int64_t size, uint64_t gpa_rebased);
100+
struct secure_world_memory {
101+
/* The secure world base address of GPA for secure world*/
102+
uint64_t base_gpa;
103+
/* The secure world base address of HPA */
104+
uint64_t base_hpa;
105+
/* Secure world runtime memory size */
106+
uint64_t length;
107+
/* The secure world base address of GPA in SOS */
108+
uint64_t gpa_sos;
109+
/* The secure world base address of GPA in UOS for normal world */
110+
uint64_t gpa_uos;
111+
};
112+
113+
#else
93114
struct secure_world_memory {
94115
/* The secure world base address of GPA in SOS */
95116
uint64_t base_gpa;
@@ -98,6 +119,7 @@ struct secure_world_memory {
98119
/* Secure world runtime memory size */
99120
uint64_t length;
100121
};
122+
#endif
101123

102124
struct secure_world_control {
103125
/* Whether secure world is enabled for current VM */

0 commit comments

Comments
 (0)