From 7a62154e36a32aebd2b32f6abd574c8176474fec Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Fri, 30 Nov 2018 16:31:16 +0800 Subject: [PATCH] hv: remove the theoretic infinite loop There may the theoretic infinite loop with some code. But actually it doesn't. This patch make these code more obvious it's not a potentially infinite loop. Tracked-On: #861 Signed-off-by: Li, Fei1 --- hypervisor/arch/x86/guest/instr_emul.c | 4 +-- hypervisor/arch/x86/guest/instr_emul.h | 3 +- hypervisor/arch/x86/notify.c | 3 +- hypervisor/arch/x86/pm.c | 7 ++--- hypervisor/common/softirq.c | 10 ++----- hypervisor/lib/string.c | 38 +++++++++++++++----------- 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/hypervisor/arch/x86/guest/instr_emul.c b/hypervisor/arch/x86/guest/instr_emul.c index 9340c5043..5b5d70891 100644 --- a/hypervisor/arch/x86/guest/instr_emul.c +++ b/hypervisor/arch/x86/guest/instr_emul.c @@ -1669,9 +1669,9 @@ static bool segment_override(uint8_t x, enum cpu_reg_name *seg) static int decode_prefixes(struct instr_emul_vie *vie, enum vm_cpu_mode cpu_mode, bool cs_d) { - uint8_t x; + uint8_t x, i; - while (1) { + for (i = 0U; i < VIE_PREFIX_SIZE; i++) { if (vie_peek(vie, &x) != 0) { return -1; } diff --git a/hypervisor/arch/x86/guest/instr_emul.h b/hypervisor/arch/x86/guest/instr_emul.h index 362f164f9..21e5b7596 100644 --- a/hypervisor/arch/x86/guest/instr_emul.h +++ b/hypervisor/arch/x86/guest/instr_emul.h @@ -87,7 +87,8 @@ struct instr_emul_vie_op { uint16_t op_flags; }; -#define VIE_INST_SIZE 15U +#define VIE_PREFIX_SIZE 4U +#define VIE_INST_SIZE 15U struct instr_emul_vie { uint8_t inst[VIE_INST_SIZE]; /* instruction bytes */ uint8_t num_valid; /* size of the instruction */ diff --git a/hypervisor/arch/x86/notify.c b/hypervisor/arch/x86/notify.c index f39ffc457..2048e3528 100644 --- a/hypervisor/arch/x86/notify.c +++ b/hypervisor/arch/x86/notify.c @@ -35,8 +35,7 @@ void smp_call_function(uint64_t mask, smp_call_func_t func, void *data) struct smp_call_info_data *smp_call; /* wait for previous smp call complete, which may run on other cpus */ - while (atomic_cmpxchg64(&smp_call_mask, 0UL, mask & INVALID_BIT_INDEX) - != 0UL); + while (atomic_cmpxchg64(&smp_call_mask, 0UL, mask & INVALID_BIT_INDEX) != 0UL); pcpu_id = ffs64(mask); while (pcpu_id != INVALID_BIT_INDEX) { bitmap_clear_nolock(pcpu_id, &mask); diff --git a/hypervisor/arch/x86/pm.c b/hypervisor/arch/x86/pm.c index b032748b2..d99f0257a 100644 --- a/hypervisor/arch/x86/pm.c +++ b/hypervisor/arch/x86/pm.c @@ -99,7 +99,7 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, acpi_gas_write(&(sx_data->pm1b_cnt), pm1b_cnt_val); } - while (1) { + do { /* polling PM1 state register to detect wether * the Sx state enter is interrupted by wakeup event. */ @@ -117,10 +117,7 @@ void do_acpi_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, * WAK_STS(bit 15) is set if system will transition to working * state. */ - if ((s1 & (1U << BIT_WAK_STS)) != 0U) { - break; - } - } + } while ((s1 & (1U << BIT_WAK_STS)) == 0U); } void enter_s3(struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val) diff --git a/hypervisor/common/softirq.c b/hypervisor/common/softirq.c index 12a86e8a6..0b5467e7b 100644 --- a/hypervisor/common/softirq.c +++ b/hypervisor/common/softirq.c @@ -32,18 +32,14 @@ void fire_softirq(uint16_t nr) void do_softirq(void) { - uint16_t nr; uint16_t cpu_id = get_cpu_id(); volatile uint64_t *softirq_pending_bitmap = &per_cpu(softirq_pending, cpu_id); + uint16_t nr = ffs64(*softirq_pending_bitmap); - while (true) { - nr = ffs64(*softirq_pending_bitmap); - if (nr >= NR_SOFTIRQS) { - break; - } - + while (nr < NR_SOFTIRQS) { bitmap_clear_lock(nr, softirq_pending_bitmap); (*softirq_handlers[nr])(cpu_id); + nr = ffs64(*softirq_pending_bitmap); } } diff --git a/hypervisor/lib/string.c b/hypervisor/lib/string.c index 6a1ef1644..03e107476 100644 --- a/hypervisor/lib/string.c +++ b/hypervisor/lib/string.c @@ -14,6 +14,21 @@ static inline bool is_space(char c) return ((c == ' ') || (c == '\t')); } +static inline char hex_digit_value (char ch) +{ + char c; + if ('0' <= ch && ch <= '9') { + c = ch - '0'; + } else if ('a' <= ch && ch <= 'f') { + c = ch - 'a' + 10; + } else if ('A' <= ch && ch <= 'F') { + c = ch - 'A' + 10; + } else { + c = -1; + } + return c; +} + /* * Convert a string to a long integer - decimal support only. */ @@ -99,7 +114,7 @@ long strtol_deci(const char *nptr) uint64_t strtoul_hex(const char *nptr) { const char *s = nptr; - char c; + char c, digit; uint64_t acc, cutoff, cutlim; uint64_t base = 16UL; int any; @@ -121,29 +136,20 @@ uint64_t strtoul_hex(const char *nptr) cutlim = ULONG_MAX % base; acc = 0UL; any = 0; - do { - if ((c >= '0') && (c <= '9')) { - c -= '0'; - } else if ((c >= 'A') && (c <= 'F')) { - c -= 'A' - 10; - } else if ((c >= 'a') && (c <= 'f')) { - c -= 'a' - 10; - } else { - break; - } - - if ((acc > cutoff) || - ((acc == cutoff) && ((uint64_t)c > cutlim))) { + digit = hex_digit_value(c); + while (digit >= 0) { + if ((acc > cutoff) || ((acc == cutoff) && ((uint64_t)digit > cutlim))) { any = -1; break; } else { acc *= base; - acc += c; + acc += digit; } c = *s; s++; - } while (true); + digit = hex_digit_value(c); + } if (any < 0) { acc = ULONG_MAX;