Skip to content

Commit 55e5ed2

Browse files
mingqiangchiwenlingz
authored andcommitted
hv:move ept violation handler to io_emul.c
move this api from ept.c to io_emul.c to avoid reverse dependency. Tracked-On: #1842 Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
1 parent 1d98b70 commit 55e5ed2

File tree

6 files changed

+95
-94
lines changed

6 files changed

+95
-94
lines changed

doc/developer-guides/hld/hv-io-emulation.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,6 @@ The following APIs are provided for I/O emulation at runtime:
341341

342342
.. doxygenfunction:: pio_instr_vmexit_handler
343343
:project: Project ACRN
344+
345+
.. doxygenfunction:: ept_violation_vmexit_handler
346+
:project: Project ACRN

doc/developer-guides/hld/hv-memmgt.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,6 @@ EPT
460460
.. doxygenfunction:: invept
461461
:project: Project ACRN
462462

463-
.. doxygenfunction:: ept_violation_vmexit_handler
464-
:project: Project ACRN
465-
466463
.. doxygenfunction:: ept_misconfig_vmexit_handler
467464
:project: Project ACRN
468465

hypervisor/arch/x86/ept.c

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -72,88 +72,6 @@ uint64_t vm0_hpa2gpa(uint64_t hpa)
7272
return hpa;
7373
}
7474

75-
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
76-
{
77-
int32_t status = -EINVAL, ret;
78-
uint64_t exit_qual;
79-
uint64_t gpa;
80-
struct io_request *io_req = &vcpu->req;
81-
struct mmio_request *mmio_req = &io_req->reqs.mmio;
82-
83-
/* Handle page fault from guest */
84-
exit_qual = vcpu->arch.exit_qualification;
85-
86-
io_req->type = REQ_MMIO;
87-
88-
/* Specify if read or write operation */
89-
if ((exit_qual & 0x2UL) != 0UL) {
90-
/* Write operation */
91-
mmio_req->direction = REQUEST_WRITE;
92-
mmio_req->value = 0UL;
93-
94-
/* XXX: write access while EPT perm RX -> WP */
95-
if ((exit_qual & 0x38UL) == 0x28UL) {
96-
io_req->type = REQ_WP;
97-
}
98-
} else {
99-
/* Read operation */
100-
mmio_req->direction = REQUEST_READ;
101-
102-
/* TODO: Need to determine how sign extension is determined for
103-
* reads
104-
*/
105-
}
106-
107-
/* Get the guest physical address */
108-
gpa = exec_vmread64(VMX_GUEST_PHYSICAL_ADDR_FULL);
109-
110-
TRACE_2L(TRACE_VMEXIT_EPT_VIOLATION, exit_qual, gpa);
111-
112-
/* Adjust IPA appropriately and OR page offset to get full IPA of abort
113-
*/
114-
mmio_req->address = gpa;
115-
116-
ret = decode_instruction(vcpu);
117-
if (ret > 0) {
118-
mmio_req->size = (uint64_t)ret;
119-
/*
120-
* For MMIO write, ask DM to run MMIO emulation after
121-
* instruction emulation. For MMIO read, ask DM to run MMIO
122-
* emulation at first.
123-
*/
124-
125-
/* Determine value being written. */
126-
if (mmio_req->direction == REQUEST_WRITE) {
127-
status = emulate_instruction(vcpu);
128-
if (status != 0) {
129-
ret = -EFAULT;
130-
}
131-
}
132-
133-
if (ret > 0) {
134-
status = emulate_io(vcpu, io_req);
135-
if (status == 0) {
136-
emulate_mmio_post(vcpu, io_req);
137-
} else {
138-
if (status == IOREQ_PENDING) {
139-
status = 0;
140-
}
141-
}
142-
}
143-
} else {
144-
if (ret == -EFAULT) {
145-
pr_info("page fault happen during decode_instruction");
146-
status = 0;
147-
}
148-
}
149-
150-
if (ret <= 0) {
151-
pr_acrnlog("Guest Linear Address: 0x%016llx", exec_vmread(VMX_GUEST_LINEAR_ADDR));
152-
pr_acrnlog("Guest Physical Address address: 0x%016llx", gpa);
153-
}
154-
return status;
155-
}
156-
15775
int32_t ept_misconfig_vmexit_handler(__unused struct acrn_vcpu *vcpu)
15876
{
15977
int32_t status;

hypervisor/arch/x86/io_emul.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,87 @@ int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu)
403403
return status;
404404
}
405405

406+
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
407+
{
408+
int32_t status = -EINVAL, ret;
409+
uint64_t exit_qual;
410+
uint64_t gpa;
411+
struct io_request *io_req = &vcpu->req;
412+
struct mmio_request *mmio_req = &io_req->reqs.mmio;
413+
414+
/* Handle page fault from guest */
415+
exit_qual = vcpu->arch.exit_qualification;
416+
417+
io_req->type = REQ_MMIO;
418+
419+
/* Specify if read or write operation */
420+
if ((exit_qual & 0x2UL) != 0UL) {
421+
/* Write operation */
422+
mmio_req->direction = REQUEST_WRITE;
423+
mmio_req->value = 0UL;
424+
425+
/* XXX: write access while EPT perm RX -> WP */
426+
if ((exit_qual & 0x38UL) == 0x28UL) {
427+
io_req->type = REQ_WP;
428+
}
429+
} else {
430+
/* Read operation */
431+
mmio_req->direction = REQUEST_READ;
432+
433+
/* TODO: Need to determine how sign extension is determined for
434+
* reads
435+
*/
436+
}
437+
438+
/* Get the guest physical address */
439+
gpa = exec_vmread64(VMX_GUEST_PHYSICAL_ADDR_FULL);
440+
441+
TRACE_2L(TRACE_VMEXIT_EPT_VIOLATION, exit_qual, gpa);
442+
443+
/* Adjust IPA appropriately and OR page offset to get full IPA of abort
444+
*/
445+
mmio_req->address = gpa;
446+
447+
ret = decode_instruction(vcpu);
448+
if (ret > 0) {
449+
mmio_req->size = (uint64_t)ret;
450+
/*
451+
* For MMIO write, ask DM to run MMIO emulation after
452+
* instruction emulation. For MMIO read, ask DM to run MMIO
453+
* emulation at first.
454+
*/
455+
456+
/* Determine value being written. */
457+
if (mmio_req->direction == REQUEST_WRITE) {
458+
status = emulate_instruction(vcpu);
459+
if (status != 0) {
460+
ret = -EFAULT;
461+
}
462+
}
463+
464+
if (ret > 0) {
465+
status = emulate_io(vcpu, io_req);
466+
if (status == 0) {
467+
emulate_mmio_post(vcpu, io_req);
468+
} else {
469+
if (status == IOREQ_PENDING) {
470+
status = 0;
471+
}
472+
}
473+
}
474+
} else {
475+
if (ret == -EFAULT) {
476+
pr_info("page fault happen during decode_instruction");
477+
status = 0;
478+
}
479+
}
480+
481+
if (ret <= 0) {
482+
pr_acrnlog("Guest Linear Address: 0x%016llx", exec_vmread(VMX_GUEST_LINEAR_ADDR));
483+
pr_acrnlog("Guest Physical Address address: 0x%016llx", gpa);
484+
}
485+
return status;
486+
}
406487

407488
/**
408489
* @brief Allow a VM to access a port I/O range

hypervisor/include/arch/x86/io_emul.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ int32_t emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req);
7979
*/
8080
int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu);
8181

82+
/**
83+
* @brief EPT violation handling
84+
*
85+
* @param[in] vcpu the pointer that points to vcpu data structure
86+
*
87+
* @retval -EINVAL fail to handle the EPT violation
88+
* @retval 0 Success to handle the EPT violation
89+
*/
90+
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu);
91+
8292
/**
8393
* @brief Allow a VM to access a port I/O range
8494
*

hypervisor/include/arch/x86/mmu.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,15 +294,7 @@ void ept_mr_modify(struct acrn_vm *vm, uint64_t *pml4_page, uint64_t gpa,
294294
*/
295295
void ept_mr_del(struct acrn_vm *vm, uint64_t *pml4_page, uint64_t gpa,
296296
uint64_t size);
297-
/**
298-
* @brief EPT violation handling
299-
*
300-
* @param[in] vcpu the pointer that points to vcpu data structure
301-
*
302-
* @retval -EINVAL fail to handle the EPT violation
303-
* @retval 0 Success to handle the EPT violation
304-
*/
305-
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu);
297+
306298
/**
307299
* @brief EPT misconfiguration handling
308300
*

0 commit comments

Comments
 (0)