Skip to content

Commit 71e1ae1

Browse files
JasonChenCJlijinxia
authored andcommitted
hypercall: add set_memmaps hypercall support
Add set_memmaps hypercall to support multi regions memmap. Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent e2b7f3c commit 71e1ae1

File tree

4 files changed

+134
-36
lines changed

4 files changed

+134
-36
lines changed

hypervisor/arch/x86/guest/vmcall.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
110110
ret = hcall_set_vm_memmap(vm, param1, param2);
111111
break;
112112

113+
case HC_VM_SET_MEMMAPS:
114+
ret = hcall_set_vm_memmaps(vm, param1);
115+
break;
116+
113117
case HC_VM_PCI_MSIX_REMAP:
114118
ret = hcall_remap_pci_msix(vm, param1, param2);
115119
break;

hypervisor/common/hypercall.c

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -413,46 +413,24 @@ int64_t hcall_notify_req_finish(uint64_t vmid, uint64_t vcpu_id)
413413
return ret;
414414
}
415415

416-
int64_t hcall_set_vm_memmap(struct vm *vm, uint64_t vmid, uint64_t param)
416+
int64_t _set_vm_memmap(struct vm *vm, struct vm *target_vm,
417+
struct vm_set_memmap *memmap)
417418
{
418-
int64_t ret = 0;
419419
uint64_t hpa;
420420
uint32_t attr, prot;
421-
struct vm_set_memmap memmap;
422-
struct vm *target_vm = get_vm_from_vmid(vmid);
423-
424-
if (!vm || !target_vm)
425-
return -1;
426-
427-
memset((void *)&memmap, 0, sizeof(memmap));
428-
429-
if (copy_from_vm(vm, &memmap, param, sizeof(memmap))) {
430-
pr_err("%s: Unable copy param to vm\n", __func__);
431-
return -1;
432-
}
433-
434-
if (!is_vm0(vm)) {
435-
pr_err("%s: ERROR! Not coming from service vm", __func__);
436-
return -1;
437-
}
438421

439-
if (is_vm0(target_vm)) {
440-
pr_err("%s: ERROR! Targeting to service vm", __func__);
441-
return -1;
442-
}
443-
444-
if ((memmap.length & 0xFFF) != 0) {
422+
if ((memmap->length & 0xFFF) != 0) {
445423
pr_err("%s: ERROR! [vm%d] map size 0x%x is not page aligned",
446-
__func__, vmid, memmap.length);
424+
__func__, target_vm->attr.id, memmap->length);
447425
return -1;
448426
}
449427

450-
hpa = gpa2hpa(vm, memmap.vm0_gpa);
428+
hpa = gpa2hpa(vm, memmap->vm0_gpa);
451429
dev_dbg(ACRN_DBG_HYCALL, "[vm%d] gpa=0x%x hpa=0x%x size=0x%x",
452-
vmid, memmap.remote_gpa, hpa, memmap.length);
430+
target_vm->attr.id, memmap->remote_gpa, hpa, memmap->length);
453431

454432
if (((hpa <= CONFIG_RAM_START) &&
455-
(hpa + memmap.length > CONFIG_RAM_START)) ||
433+
(hpa + memmap->length > CONFIG_RAM_START)) ||
456434
((hpa >= CONFIG_RAM_START) &&
457435
(hpa < CONFIG_RAM_START + CONFIG_RAM_SIZE))) {
458436
pr_err("%s: ERROR! overlap the HV memory region.", __func__);
@@ -461,8 +439,8 @@ int64_t hcall_set_vm_memmap(struct vm *vm, uint64_t vmid, uint64_t param)
461439

462440
/* Check prot */
463441
attr = 0;
464-
if (memmap.type != MAP_UNMAP) {
465-
prot = memmap.prot;
442+
if (memmap->type != MAP_UNMAP) {
443+
prot = (memmap->prot != 0) ? memmap->prot : memmap->prot_2;
466444
if (prot & MEM_ACCESS_READ)
467445
attr |= MMU_MEM_ATTR_READ;
468446
if (prot & MEM_ACCESS_WRITE)
@@ -484,10 +462,78 @@ int64_t hcall_set_vm_memmap(struct vm *vm, uint64_t vmid, uint64_t param)
484462
}
485463

486464
/* create gpa to hpa EPT mapping */
487-
ret = ept_mmap(target_vm, hpa,
488-
memmap.remote_gpa, memmap.length, memmap.type, attr);
465+
return ept_mmap(target_vm, hpa,
466+
memmap->remote_gpa, memmap->length, memmap->type, attr);
467+
}
489468

490-
return ret;
469+
int64_t hcall_set_vm_memmap(struct vm *vm, uint64_t vmid, uint64_t param)
470+
{
471+
struct vm_set_memmap memmap;
472+
struct vm *target_vm = get_vm_from_vmid(vmid);
473+
474+
if (!vm || !target_vm)
475+
return -1;
476+
477+
memset((void *)&memmap, 0, sizeof(memmap));
478+
479+
if (copy_from_vm(vm, &memmap, param, sizeof(memmap))) {
480+
pr_err("%s: Unable copy param to vm\n", __func__);
481+
return -1;
482+
}
483+
484+
if (!is_vm0(vm)) {
485+
pr_err("%s: ERROR! Not coming from service vm", __func__);
486+
return -1;
487+
}
488+
489+
if (is_vm0(target_vm)) {
490+
pr_err("%s: ERROR! Targeting to service vm", __func__);
491+
return -1;
492+
}
493+
494+
return _set_vm_memmap(vm, target_vm, &memmap);
495+
}
496+
497+
int64_t hcall_set_vm_memmaps(struct vm *vm, uint64_t param)
498+
{
499+
struct set_memmaps set_memmaps;
500+
struct memory_map *regions;
501+
struct vm *target_vm;
502+
unsigned int idx;
503+
504+
if (!is_vm0(vm)) {
505+
pr_err("%s: ERROR! Not coming from service vm",
506+
__func__);
507+
return -1;
508+
}
509+
510+
memset((void *)&set_memmaps, 0, sizeof(set_memmaps));
511+
512+
if (copy_from_vm(vm, &set_memmaps, param, sizeof(set_memmaps))) {
513+
pr_err("%s: Unable copy param from vm\n", __func__);
514+
return -1;
515+
}
516+
517+
target_vm = get_vm_from_vmid(set_memmaps.vmid);
518+
if (is_vm0(target_vm)) {
519+
pr_err("%s: ERROR! Targeting to service vm",
520+
__func__);
521+
return -1;
522+
}
523+
524+
idx = 0;
525+
/*TODO: use copy_from_vm for this buffer page */
526+
regions = GPA2HVA(vm, set_memmaps.memmaps_gpa);
527+
while (idx < set_memmaps.memmaps_num) {
528+
/* the force pointer change below is for back compatible
529+
* to struct vm_set_memmap, it will be removed in the future
530+
*/
531+
if (_set_vm_memmap(vm, target_vm,
532+
(struct vm_set_memmap *)&regions[idx]) < 0)
533+
return -1;
534+
idx++;
535+
}
536+
return 0;
491537
}
492538

493539
int64_t hcall_remap_pci_msix(struct vm *vm, uint64_t vmid, uint64_t param)

hypervisor/include/common/hypercall.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,17 @@ int64_t hcall_notify_req_finish(uint64_t vmid, uint64_t param);
237237
*/
238238
int64_t hcall_set_vm_memmap(struct vm *vm, uint64_t vmid, uint64_t param);
239239

240+
/**
241+
* @brief setup ept memmory mapping for multi regions
242+
*
243+
* @param vm Pointer to VM data structure
244+
* @param param guest physical address. This gpa points to
245+
* struct set_memmaps
246+
*
247+
* @return 0 on success, non-zero on error.
248+
*/
249+
int64_t hcall_set_vm_memmaps(struct vm *vm, uint64_t param);
250+
240251
/**
241252
* @brief remap PCI MSI interrupt
242253
*

hypervisor/include/public/acrn_hv_defs.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#define HC_ID_MEM_BASE 0x40UL
8181
#define HC_VM_SET_MEMMAP _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x00)
8282
#define HC_VM_GPA2HPA _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x01)
83+
#define HC_VM_SET_MEMMAPS _HC_ID(HC_ID, HC_ID_MEM_BASE + 0x02)
8384

8485
/* PCI assignment*/
8586
#define HC_ID_PCI_BASE 0x50UL
@@ -140,8 +141,8 @@ struct vm_set_memmap {
140141
/** map type: MAP_MEM, MAP_MMIO or MAP_UNMAP */
141142
uint32_t type;
142143

143-
/** reserved for alignment padding */
144-
uint32_t reserved;
144+
/** memory attributes: memory type + RWX access right */
145+
uint32_t prot;
145146

146147
/** guest physical address to map */
147148
uint64_t remote_gpa;
@@ -152,10 +153,46 @@ struct vm_set_memmap {
152153
/** length of the map range */
153154
uint64_t length;
154155

156+
/** old memory attributes(will be removed in the future):
157+
* memory type + RWX access right */
158+
uint32_t prot_2;
159+
} __aligned(8);
160+
161+
struct memory_map {
162+
/** map type: MAP_MEM, MAP_MMIO or MAP_UNMAP */
163+
uint32_t type;
164+
155165
/** memory attributes: memory type + RWX access right */
156166
uint32_t prot;
167+
168+
/** guest physical address to map */
169+
uint64_t remote_gpa;
170+
171+
/** VM0's guest physcial address which remote gpa will be mapped to */
172+
uint64_t vm0_gpa;
173+
174+
/** length of the map range */
175+
uint64_t length;
176+
157177
} __aligned(8);
158178

179+
/**
180+
* multi memmap regions hypercall, used for HC_VM_SET_MEMMAPS
181+
*/
182+
struct set_memmaps {
183+
/** vmid for this hypercall */
184+
uint64_t vmid;
185+
186+
/** multi memmaps numbers */
187+
uint32_t memmaps_num;
188+
189+
/** the gpa of memmaps buffer, point to the memmaps array:
190+
* struct memory_map regions[memmaps_num]
191+
* the max buffer size is one page.
192+
*/
193+
uint64_t memmaps_gpa;
194+
} __attribute__((aligned(8)));
195+
159196
/**
160197
* Setup parameter for share buffer, used for HC_SETUP_SBUF hypercall
161198
*/

0 commit comments

Comments
 (0)