mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 06:29:19 +00:00
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>
This commit is contained in:
parent
1d98b7012d
commit
55e5ed2e1a
@ -341,3 +341,6 @@ The following APIs are provided for I/O emulation at runtime:
|
|||||||
|
|
||||||
.. doxygenfunction:: pio_instr_vmexit_handler
|
.. doxygenfunction:: pio_instr_vmexit_handler
|
||||||
:project: Project ACRN
|
:project: Project ACRN
|
||||||
|
|
||||||
|
.. doxygenfunction:: ept_violation_vmexit_handler
|
||||||
|
:project: Project ACRN
|
||||||
|
@ -460,9 +460,6 @@ EPT
|
|||||||
.. doxygenfunction:: invept
|
.. doxygenfunction:: invept
|
||||||
:project: Project ACRN
|
:project: Project ACRN
|
||||||
|
|
||||||
.. doxygenfunction:: ept_violation_vmexit_handler
|
|
||||||
:project: Project ACRN
|
|
||||||
|
|
||||||
.. doxygenfunction:: ept_misconfig_vmexit_handler
|
.. doxygenfunction:: ept_misconfig_vmexit_handler
|
||||||
:project: Project ACRN
|
:project: Project ACRN
|
||||||
|
|
||||||
|
@ -72,88 +72,6 @@ uint64_t vm0_hpa2gpa(uint64_t hpa)
|
|||||||
return hpa;
|
return hpa;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
|
|
||||||
{
|
|
||||||
int32_t status = -EINVAL, ret;
|
|
||||||
uint64_t exit_qual;
|
|
||||||
uint64_t gpa;
|
|
||||||
struct io_request *io_req = &vcpu->req;
|
|
||||||
struct mmio_request *mmio_req = &io_req->reqs.mmio;
|
|
||||||
|
|
||||||
/* Handle page fault from guest */
|
|
||||||
exit_qual = vcpu->arch.exit_qualification;
|
|
||||||
|
|
||||||
io_req->type = REQ_MMIO;
|
|
||||||
|
|
||||||
/* Specify if read or write operation */
|
|
||||||
if ((exit_qual & 0x2UL) != 0UL) {
|
|
||||||
/* Write operation */
|
|
||||||
mmio_req->direction = REQUEST_WRITE;
|
|
||||||
mmio_req->value = 0UL;
|
|
||||||
|
|
||||||
/* XXX: write access while EPT perm RX -> WP */
|
|
||||||
if ((exit_qual & 0x38UL) == 0x28UL) {
|
|
||||||
io_req->type = REQ_WP;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Read operation */
|
|
||||||
mmio_req->direction = REQUEST_READ;
|
|
||||||
|
|
||||||
/* TODO: Need to determine how sign extension is determined for
|
|
||||||
* reads
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the guest physical address */
|
|
||||||
gpa = exec_vmread64(VMX_GUEST_PHYSICAL_ADDR_FULL);
|
|
||||||
|
|
||||||
TRACE_2L(TRACE_VMEXIT_EPT_VIOLATION, exit_qual, gpa);
|
|
||||||
|
|
||||||
/* Adjust IPA appropriately and OR page offset to get full IPA of abort
|
|
||||||
*/
|
|
||||||
mmio_req->address = gpa;
|
|
||||||
|
|
||||||
ret = decode_instruction(vcpu);
|
|
||||||
if (ret > 0) {
|
|
||||||
mmio_req->size = (uint64_t)ret;
|
|
||||||
/*
|
|
||||||
* For MMIO write, ask DM to run MMIO emulation after
|
|
||||||
* instruction emulation. For MMIO read, ask DM to run MMIO
|
|
||||||
* emulation at first.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Determine value being written. */
|
|
||||||
if (mmio_req->direction == REQUEST_WRITE) {
|
|
||||||
status = emulate_instruction(vcpu);
|
|
||||||
if (status != 0) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret > 0) {
|
|
||||||
status = emulate_io(vcpu, io_req);
|
|
||||||
if (status == 0) {
|
|
||||||
emulate_mmio_post(vcpu, io_req);
|
|
||||||
} else {
|
|
||||||
if (status == IOREQ_PENDING) {
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ret == -EFAULT) {
|
|
||||||
pr_info("page fault happen during decode_instruction");
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret <= 0) {
|
|
||||||
pr_acrnlog("Guest Linear Address: 0x%016llx", exec_vmread(VMX_GUEST_LINEAR_ADDR));
|
|
||||||
pr_acrnlog("Guest Physical Address address: 0x%016llx", gpa);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ept_misconfig_vmexit_handler(__unused struct acrn_vcpu *vcpu)
|
int32_t ept_misconfig_vmexit_handler(__unused struct acrn_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
@ -403,6 +403,87 @@ int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
int32_t status = -EINVAL, ret;
|
||||||
|
uint64_t exit_qual;
|
||||||
|
uint64_t gpa;
|
||||||
|
struct io_request *io_req = &vcpu->req;
|
||||||
|
struct mmio_request *mmio_req = &io_req->reqs.mmio;
|
||||||
|
|
||||||
|
/* Handle page fault from guest */
|
||||||
|
exit_qual = vcpu->arch.exit_qualification;
|
||||||
|
|
||||||
|
io_req->type = REQ_MMIO;
|
||||||
|
|
||||||
|
/* Specify if read or write operation */
|
||||||
|
if ((exit_qual & 0x2UL) != 0UL) {
|
||||||
|
/* Write operation */
|
||||||
|
mmio_req->direction = REQUEST_WRITE;
|
||||||
|
mmio_req->value = 0UL;
|
||||||
|
|
||||||
|
/* XXX: write access while EPT perm RX -> WP */
|
||||||
|
if ((exit_qual & 0x38UL) == 0x28UL) {
|
||||||
|
io_req->type = REQ_WP;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Read operation */
|
||||||
|
mmio_req->direction = REQUEST_READ;
|
||||||
|
|
||||||
|
/* TODO: Need to determine how sign extension is determined for
|
||||||
|
* reads
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the guest physical address */
|
||||||
|
gpa = exec_vmread64(VMX_GUEST_PHYSICAL_ADDR_FULL);
|
||||||
|
|
||||||
|
TRACE_2L(TRACE_VMEXIT_EPT_VIOLATION, exit_qual, gpa);
|
||||||
|
|
||||||
|
/* Adjust IPA appropriately and OR page offset to get full IPA of abort
|
||||||
|
*/
|
||||||
|
mmio_req->address = gpa;
|
||||||
|
|
||||||
|
ret = decode_instruction(vcpu);
|
||||||
|
if (ret > 0) {
|
||||||
|
mmio_req->size = (uint64_t)ret;
|
||||||
|
/*
|
||||||
|
* For MMIO write, ask DM to run MMIO emulation after
|
||||||
|
* instruction emulation. For MMIO read, ask DM to run MMIO
|
||||||
|
* emulation at first.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Determine value being written. */
|
||||||
|
if (mmio_req->direction == REQUEST_WRITE) {
|
||||||
|
status = emulate_instruction(vcpu);
|
||||||
|
if (status != 0) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
status = emulate_io(vcpu, io_req);
|
||||||
|
if (status == 0) {
|
||||||
|
emulate_mmio_post(vcpu, io_req);
|
||||||
|
} else {
|
||||||
|
if (status == IOREQ_PENDING) {
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ret == -EFAULT) {
|
||||||
|
pr_info("page fault happen during decode_instruction");
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret <= 0) {
|
||||||
|
pr_acrnlog("Guest Linear Address: 0x%016llx", exec_vmread(VMX_GUEST_LINEAR_ADDR));
|
||||||
|
pr_acrnlog("Guest Physical Address address: 0x%016llx", gpa);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allow a VM to access a port I/O range
|
* @brief Allow a VM to access a port I/O range
|
||||||
|
@ -79,6 +79,16 @@ int32_t emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req);
|
|||||||
*/
|
*/
|
||||||
int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu);
|
int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EPT violation handling
|
||||||
|
*
|
||||||
|
* @param[in] vcpu the pointer that points to vcpu data structure
|
||||||
|
*
|
||||||
|
* @retval -EINVAL fail to handle the EPT violation
|
||||||
|
* @retval 0 Success to handle the EPT violation
|
||||||
|
*/
|
||||||
|
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allow a VM to access a port I/O range
|
* @brief Allow a VM to access a port I/O range
|
||||||
*
|
*
|
||||||
|
@ -294,15 +294,7 @@ void ept_mr_modify(struct acrn_vm *vm, uint64_t *pml4_page, uint64_t gpa,
|
|||||||
*/
|
*/
|
||||||
void ept_mr_del(struct acrn_vm *vm, uint64_t *pml4_page, uint64_t gpa,
|
void ept_mr_del(struct acrn_vm *vm, uint64_t *pml4_page, uint64_t gpa,
|
||||||
uint64_t size);
|
uint64_t size);
|
||||||
/**
|
|
||||||
* @brief EPT violation handling
|
|
||||||
*
|
|
||||||
* @param[in] vcpu the pointer that points to vcpu data structure
|
|
||||||
*
|
|
||||||
* @retval -EINVAL fail to handle the EPT violation
|
|
||||||
* @retval 0 Success to handle the EPT violation
|
|
||||||
*/
|
|
||||||
int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu);
|
|
||||||
/**
|
/**
|
||||||
* @brief EPT misconfiguration handling
|
* @brief EPT misconfiguration handling
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user