Skip to content

Commit 5d2ab4d

Browse files
ZideChen0lijinxia
authored andcommitted
hv: add APIs to allow updating EPT mem type
- Add PAGING_REQUEST_TYPE_MODIFY_MT memory map request type - Update map_mem_region() to allow modifying the memory type related fields in a page table entry - Add ept_update_mt() - add modify_mem_mt() for both EPT and MMU Signed-off-by: Zide Chen <zide.chen@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent b435c74 commit 5d2ab4d

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

hypervisor/arch/x86/ept.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,24 @@ int ept_mmap(struct vm *vm, uint64_t hpa,
489489

490490
return 0;
491491
}
492+
493+
int ept_update_mt(struct vm *vm, uint64_t hpa,
494+
uint64_t gpa, uint64_t size, uint32_t prot)
495+
{
496+
struct map_params map_params;
497+
struct vcpu *vcpu;
498+
int i;
499+
500+
/* Setup memory map parameters */
501+
map_params.page_table_type = PTT_EPT;
502+
map_params.pml4_base = HPA2HVA(vm->arch_vm.nworld_eptp);
503+
map_params.pml4_inverted = HPA2HVA(vm->arch_vm.m2p);
504+
505+
modify_mem_mt(&map_params, (void *)hpa, (void *)gpa, size, prot);
506+
507+
foreach_vcpu(i, vm, vcpu) {
508+
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
509+
}
510+
511+
return 0;
512+
}

hypervisor/arch/x86/mmu.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ enum mem_map_request_type {
3535
PAGING_REQUEST_TYPE_MAP = 0, /* Creates a new mapping. */
3636
PAGING_REQUEST_TYPE_UNMAP = 1, /* Removes a pre-existing entry */
3737
PAGING_REQUEST_TYPE_MODIFY = 2,
38+
PAGING_REQUEST_TYPE_MODIFY_MT = 3, /* Update the memory type fields */
3839
/* Modifies a pre-existing entries attributes. */
3940
PAGING_REQUEST_TYPE_UNKNOWN,
4041
};
@@ -375,6 +376,28 @@ static uint32_t map_mem_region(void *vaddr, void *paddr,
375376
mmu_need_invtlb = true;
376377
break;
377378
}
379+
case PAGING_REQUEST_TYPE_MODIFY_MT:
380+
{
381+
if (prev_entry_present) {
382+
/* modify the memory type related fields only */
383+
if (table_type == PTT_EPT)
384+
table_entry = entry & ~IA32E_EPT_MT_MASK;
385+
else
386+
table_entry = entry & ~MMU_MEM_ATTR_TYPE_MASK;
387+
388+
table_entry |= attr;
389+
390+
/* Write the table entry to map this memory */
391+
MEM_WRITE64(table_base + table_offset, table_entry);
392+
393+
/* Modify, need to invalidate TLB and
394+
* page-structure cache
395+
*/
396+
if (table_type == PTT_HOST)
397+
mmu_need_invtlb = true;
398+
}
399+
break;
400+
}
378401
default:
379402
ASSERT(0, "Bad memory map request type");
380403
return 0;
@@ -1124,3 +1147,23 @@ int modify_mem(struct map_params *map_params, void *paddr, void *vaddr,
11241147
}
11251148
return ret;
11261149
}
1150+
1151+
int modify_mem_mt(struct map_params *map_params, void *paddr, void *vaddr,
1152+
uint64_t size, uint32_t flags)
1153+
{
1154+
int ret = 0;
1155+
1156+
/* used for MMU and EPT*/
1157+
ret = modify_paging(map_params, paddr, vaddr, size, flags,
1158+
PAGING_REQUEST_TYPE_MODIFY_MT, true);
1159+
if (ret < 0)
1160+
return ret;
1161+
1162+
/* only for EPT */
1163+
if (map_params->page_table_type == PTT_EPT) {
1164+
ret = modify_paging(map_params, vaddr, paddr, size, flags,
1165+
PAGING_REQUEST_TYPE_MODIFY_MT, false);
1166+
}
1167+
return ret;
1168+
}
1169+

hypervisor/include/arch/x86/mmu.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define IA32E_EPT_WT (4<<3)
2929
#define IA32E_EPT_WP (5<<3)
3030
#define IA32E_EPT_WB (6<<3)
31+
#define IA32E_EPT_MT_MASK (7<<3)
3132
#define IA32E_EPT_PAT_IGNORE 0x0000000000000040
3233
#define IA32E_EPT_ACCESS_FLAG 0x0000000000000100
3334
#define IA32E_EPT_DIRTY_FLAG 0x0000000000000200
@@ -216,6 +217,9 @@
216217
/* Selects PAT7 WP */
217218
#define MMU_MEM_ATTR_TYPE_WRITE_PROTECTED \
218219
(IA32E_PDPTE_PAT_BIT | IA32E_COMM_PCD_BIT | IA32E_COMM_PWT_BIT)
220+
/* memory type bits mask */
221+
#define MMU_MEM_ATTR_TYPE_MASK \
222+
(IA32E_PDPTE_PAT_BIT | IA32E_COMM_PCD_BIT | IA32E_COMM_PWT_BIT)
219223

220224
#define ROUND_PAGE_UP(addr) (((addr) + CPU_PAGE_SIZE - 1) & CPU_PAGE_MASK)
221225
#define ROUND_PAGE_DOWN(addr) ((addr) & CPU_PAGE_MASK)
@@ -302,6 +306,8 @@ int unmap_mem(struct map_params *map_params, void *paddr, void *vaddr,
302306
uint64_t size, uint32_t flags);
303307
int modify_mem(struct map_params *map_params, void *paddr, void *vaddr,
304308
uint64_t size, uint32_t flags);
309+
int modify_mem_mt(struct map_params *map_params, void *paddr, void *vaddr,
310+
uint64_t size, uint32_t flags);
305311
int check_vmx_mmu_cap(void);
306312
int allocate_vpid(void);
307313
void flush_vpid_single(int vpid);
@@ -375,6 +381,8 @@ uint64_t _gpa2hpa(struct vm *vm, uint64_t gpa, uint32_t *size);
375381
uint64_t hpa2gpa(struct vm *vm, uint64_t hpa);
376382
int ept_mmap(struct vm *vm, uint64_t hpa,
377383
uint64_t gpa, uint64_t size, uint32_t type, uint32_t prot);
384+
int ept_update_mt(struct vm *vm, uint64_t hpa,
385+
uint64_t gpa, uint64_t size, uint32_t prot);
378386

379387
int ept_violation_vmexit_handler(struct vcpu *vcpu);
380388
int ept_misconfig_vmexit_handler(struct vcpu *vcpu);

0 commit comments

Comments
 (0)