From 8e00180c9f1d70172229b911755bb7444524f19c Mon Sep 17 00:00:00 2001 From: Chaohong guo Date: Thu, 20 Dec 2018 11:56:00 +0800 Subject: [PATCH] HV: Remove goto statement in guest.c To meet MISRA, remove some goto statements in guest.c Tracked-On: #861 Signed-off-by: Chaohong guo Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/guest.c | 237 ++++++++++++++---------------- 1 file changed, 111 insertions(+), 126 deletions(-) diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index eeba964b3..93e8ac588 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -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; - 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); + } - 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 if the entry present */ - if ((entry & PAGE_PRESENT) == 0U) { - ret = -EFAULT; - goto out; - } - - /* 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) { + /* check if the entry present */ + if ((entry & PAGE_PRESENT) == 0U) { fault = 1; - goto out; + } + + /* 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; } } - 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) { + /* 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; - goto out; } + + /* check for U/S */ + if ((fault == 0) && (entry & PAGE_USER) == 0U) { + is_user_mode_addr = false; + + if (pw_info->is_user_mode_access) { + fault = 1; + } + } + + + 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); + 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; - } - - /* 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; } @@ -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; + 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); + } } - index = (gva >> 30U) & 0x3UL; - entry = base[index]; - - if ((entry & PAGE_PRESENT) == 0U) { - ret = -EFAULT; - goto out; - } - - pw_info->level = 2U; - pw_info->top_entry = entry; - ret = local_gva2gpa_common(vcpu, pw_info, gva, gpa, err_code); - -out: return ret; }