Skip to content

Commit

Permalink
HV: Remove goto statement in guest.c
Browse files Browse the repository at this point in the history
To meet MISRA, remove some goto statements in guest.c

Tracked-On: #861
Signed-off-by: Chaohong guo <chaohong.guo@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
  • Loading branch information
chaohong-guo authored and wenlingz committed Jan 2, 2019
1 parent 2e01b4c commit 8e00180
Showing 1 changed file with 109 additions and 124 deletions.
233 changes: 109 additions & 124 deletions hypervisor/arch/x86/guest/guest.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,144 +78,136 @@ static int32_t local_gva2gpa_common(struct acrn_vcpu *vcpu, const struct page_wa
uint64_t index;
uint32_t shift;
void *base;
uint64_t entry;
uint64_t addr, page_size;
uint64_t entry = 0U;
uint64_t addr;
uint64_t page_size = PAGE_SIZE_4K;
int32_t ret = 0;
int32_t fault = 0;
bool is_user_mode_addr = true;
bool is_page_rw_flags_on = true;

if (pw_info->level < 1U) {
return -EINVAL;
}
ret = -EINVAL;
} else {
addr = pw_info->top_entry;
i = pw_info->level;
stac();

addr = pw_info->top_entry;
i = pw_info->level;
stac();
while (i != 0U) {
i--;
while ((i != 0U) && (fault == 0)) {
i--;

addr = addr & IA32E_REF_MASK;
base = gpa2hva(vcpu->vm, addr);
if (base == NULL) {
ret = -EFAULT;
goto out;
}
addr = addr & IA32E_REF_MASK;
base = gpa2hva(vcpu->vm, addr);
if (base == NULL) {
fault = 1;
} else {
shift = (i * pw_info->width) + 12U;
index = (gva >> shift) & ((1UL << pw_info->width) - 1UL);
page_size = 1UL << shift;

if (pw_info->width == 10U) {
uint32_t *base32 = (uint32_t *)base;
/* 32bit entry */
entry = (uint64_t)(*(base32 + index));
} else {
uint64_t *base64 = (uint64_t *)base;
entry = *(base64 + index);
}

shift = (i * pw_info->width) + 12U;
index = (gva >> shift) & ((1UL << pw_info->width) - 1UL);
page_size = 1UL << shift;
/* check if the entry present */
if ((entry & PAGE_PRESENT) == 0U) {
fault = 1;
}

if (pw_info->width == 10U) {
uint32_t *base32 = (uint32_t *)base;
/* 32bit entry */
entry = (uint64_t)(*(base32 + index));
} else {
uint64_t *base64 = (uint64_t *)base;
entry = *(base64 + index);
}
/* check for R/W */
if ((fault == 0) && (entry & PAGE_RW) == 0U) {
if ((pw_info->is_write_access) &&
(pw_info->is_user_mode_access || pw_info->wp)) {
/* Case1: Supermode and wp is 1
* Case2: Usermode */
fault = 1;
}
is_page_rw_flags_on = false;
}
}

/* check if the entry present */
if ((entry & PAGE_PRESENT) == 0U) {
ret = -EFAULT;
goto out;
}
/* check for nx, since for 32-bit paing, the XD bit is
* reserved(0), use the same logic as PAE/4-level paging */
if ((fault == 0) && pw_info->is_inst_fetch && pw_info->nxe &&
((entry & PAGE_NX) != 0U)) {
fault = 1;
}

/* check for U/S */
if ((fault == 0) && (entry & PAGE_USER) == 0U) {
is_user_mode_addr = false;

/* check for R/W */
if ((entry & PAGE_RW) == 0U) {
if (pw_info->is_write_access) {
/* Case1: Supermode and wp is 1
* Case2: Usermode */
if (pw_info->is_user_mode_access ||
pw_info->wp) {
if (pw_info->is_user_mode_access) {
fault = 1;
goto out;
}
}
is_page_rw_flags_on = false;
}

/* check for nx, since for 32-bit paing, the XD bit is
* reserved(0), use the same logic as PAE/4-level paging */
if (pw_info->is_inst_fetch && pw_info->nxe &&
((entry & PAGE_NX) != 0U)) {
fault = 1;
goto out;
}

/* check for U/S */
if ((entry & PAGE_USER) == 0U) {
is_user_mode_addr = false;

if (pw_info->is_user_mode_access) {
fault = 1;
goto out;
if ((fault == 0) && pw_info->pse &&
((i > 0U) && ((entry & PAGE_PSE) != 0U))) {
break;
}
addr = entry;
}

if (pw_info->pse && ((i > 0U) && ((entry & PAGE_PSE) != 0U))) {
break;
}
addr = entry;
}

/* When SMAP/SMEP is on, we only need to apply check when address is
* user-mode address.
* Also SMAP/SMEP only impact the supervisor-mode access.
*/
/* if smap is enabled and supervisor-mode access */
if (pw_info->is_smap_on && !pw_info->is_user_mode_access &&
/* When SMAP/SMEP is on, we only need to apply check when address is
* user-mode address.
* Also SMAP/SMEP only impact the supervisor-mode access.
*/
/* if smap is enabled and supervisor-mode access */
if ((fault == 0) && pw_info->is_smap_on && !pw_info->is_user_mode_access &&
is_user_mode_addr) {
bool rflags_ac = ((vcpu_get_rflags(vcpu) & RFLAGS_AC) != 0UL);

/* read from user mode address, eflags.ac = 0 */
if (!pw_info->is_write_access && !rflags_ac) {
fault = 1;
goto out;
}
bool rflags_ac = ((vcpu_get_rflags(vcpu) & RFLAGS_AC) != 0UL);

/* write to user mode address */
if (pw_info->is_write_access) {
/* cr0.wp = 0, eflags.ac = 0 */
if (!pw_info->wp && !rflags_ac) {
/* read from user mode address, eflags.ac = 0 */
if (!pw_info->is_write_access && !rflags_ac) {
fault = 1;
goto out;
}
} else if (pw_info->is_write_access) {
/* write to user mode address */

/* cr0.wp = 1, eflags.ac = 1, r/w flag is 0
* on any paging structure entry
*/
if (pw_info->wp && rflags_ac && !is_page_rw_flags_on) {
fault = 1;
goto out;
}
/* cr0.wp = 0, eflags.ac = 0 */
if (!pw_info->wp && !rflags_ac) {
fault = 1;
}

/* cr0.wp = 1, eflags.ac = 0 */
if (pw_info->wp && !rflags_ac) {
fault = 1;
goto out;
/* cr0.wp = 1, eflags.ac = 1, r/w flag is 0
* on any paging structure entry
*/
if (pw_info->wp && rflags_ac && !is_page_rw_flags_on) {
fault = 1;
}

/* cr0.wp = 1, eflags.ac = 0 */
if (pw_info->wp && !rflags_ac) {
fault = 1;
}
}
}
}

/* instruction fetch from user-mode address, smep on */
if (pw_info->is_smep_on && !pw_info->is_user_mode_access &&
/* instruction fetch from user-mode address, smep on */
if ((fault == 0) && pw_info->is_smep_on && !pw_info->is_user_mode_access &&
is_user_mode_addr && pw_info->is_inst_fetch) {
fault = 1;
goto out;
}
fault = 1;
}

entry >>= shift;
/* shift left 12bit more and back to clear XD/Prot Key/Ignored bits */
entry <<= (shift + 12U);
entry >>= 12U;
*gpa = entry | (gva & (page_size - 1UL));
out:
if (fault == 0) {
entry >>= shift;
/* shift left 12bit more and back to clear XD/Prot Key/Ignored bits */
entry <<= (shift + 12U);
entry >>= 12U;
*gpa = entry | (gva & (page_size - 1UL));
}

clac();
if (fault != 0) {
ret = -EFAULT;
*err_code |= PAGE_FAULT_P_FLAG;
clac();
if (fault != 0) {
ret = -EFAULT;
*err_code |= PAGE_FAULT_P_FLAG;
}
}
return ret;
}
Expand All @@ -227,28 +219,21 @@ static int32_t local_gva2gpa_pae(struct acrn_vcpu *vcpu, struct page_walk_info *
uint64_t *base;
uint64_t entry;
uint64_t addr;
int32_t ret;
int32_t ret = -EFAULT;

addr = pw_info->top_entry & 0xFFFFFFF0U;
base = (uint64_t *)gpa2hva(vcpu->vm, addr);
if (base == NULL) {
ret = -EFAULT;
goto out;
}

index = (gva >> 30U) & 0x3UL;
entry = base[index];

if ((entry & PAGE_PRESENT) == 0U) {
ret = -EFAULT;
goto out;
if (base != NULL) {
index = (gva >> 30U) & 0x3UL;
entry = base[index];

if ((entry & PAGE_PRESENT) != 0U) {
pw_info->level = 2U;
pw_info->top_entry = entry;
ret = local_gva2gpa_common(vcpu, pw_info, gva, gpa, err_code);
}
}

pw_info->level = 2U;
pw_info->top_entry = entry;
ret = local_gva2gpa_common(vcpu, pw_info, gva, gpa, err_code);

out:
return ret;
}

Expand Down

0 comments on commit 8e00180

Please sign in to comment.