diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index 5fe20d844..586843bd3 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -97,7 +97,7 @@ inline uint64_t vcpumask2pcpumask(struct vm *vm, uint64_t vdmask) uint64_t dmask = 0; struct vcpu *vcpu; - while ((vcpu_id = bitmap_ffs(&vdmask)) >= 0) { + while ((vcpu_id = ffs64(vdmask)) >= 0) { bitmap_clear(vcpu_id, &vdmask); vcpu = vcpu_from_vid(vm, vcpu_id); ASSERT(vcpu, "vcpu_from_vid failed"); diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index f5f569161..1f68f4b28 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -848,7 +848,7 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest, */ *dmask = 0; amask = vm_active_cpus(vm); - while ((vcpu_id = bitmap_ffs(&amask)) >= 0) { + while ((vcpu_id = ffs64(amask)) >= 0) { bitmap_clear(vcpu_id, &amask); vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id); @@ -997,7 +997,7 @@ vlapic_icrlo_write_handler(struct vlapic *vlapic) break; } - while ((i = bitmap_ffs(&dmask)) >= 0) { + while ((i = ffs64(dmask)) >= 0) { bitmap_clear(i, &dmask); target_vcpu = vcpu_from_vid(vlapic->vm, i); if (target_vcpu == NULL) @@ -1521,7 +1521,7 @@ vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest, bool phys, */ vlapic_calcdest(vm, &dmask, dest, phys, lowprio); - while ((vcpu_id = bitmap_ffs(&dmask)) >= 0) { + while ((vcpu_id = ffs64(dmask)) >= 0) { bitmap_clear(vcpu_id, &dmask); target_vcpu = vcpu_from_vid(vm, vcpu_id); if (target_vcpu == NULL) @@ -1667,7 +1667,7 @@ vlapic_set_local_intr(struct vm *vm, int cpu_id, int vector) else bitmap_set(cpu_id, &dmask); error = 0; - while ((cpu_id = bitmap_ffs(&dmask)) >= 0) { + while ((cpu_id = ffs64(dmask)) >= 0) { bitmap_clear(cpu_id, &dmask); vlapic = vm_lapic_from_vcpu_id(vm, cpu_id); error = vlapic_trigger_lvt(vlapic, vector); @@ -2019,7 +2019,7 @@ apicv_pending_intr(struct vlapic *vlapic, __unused int *vecptr) for (i = 3; i >= 0; i--) { pirval = pir_desc->pir[i]; if (pirval != 0) { - vpr = (i * 64 + flsl(pirval)) & 0xF0; + vpr = (i * 64 + fls64(pirval)) & 0xF0; return (vpr > ppr); } } @@ -2149,7 +2149,7 @@ apicv_inject_pir(struct vlapic *vlapic) * pending bit set, PIR 0 */ if (pirval != 0) { - rvi = pirbase + flsl(pirval); + rvi = pirbase + fls64(pirval); intr_status_old = (uint16_t) (0xFFFF & diff --git a/hypervisor/arch/x86/softirq.c b/hypervisor/arch/x86/softirq.c index c3ce04dcf..b234a58d8 100644 --- a/hypervisor/arch/x86/softirq.c +++ b/hypervisor/arch/x86/softirq.c @@ -92,7 +92,7 @@ void exec_softirq(void) goto ENABLE_AND_EXIT; while (1) { - softirq_id = bitmap_ffs(bitmap); + softirq_id = ffs64(*bitmap); if ((softirq_id < 0) || (softirq_id >= SOFTIRQ_MAX)) break; diff --git a/hypervisor/include/lib/bits.h b/hypervisor/include/lib/bits.h index 93bb6e4d1..d88013680 100644 --- a/hypervisor/include/lib/bits.h +++ b/hypervisor/include/lib/bits.h @@ -32,28 +32,6 @@ #define BUS_LOCK "lock ; " -static inline unsigned int -bsrl(unsigned int mask) -{ - unsigned int result; - - __asm __volatile("bsrl %1,%0" - : "=r" (result) - : "rm" (mask)); - return result; -} - -static inline unsigned long -bsrq(unsigned long mask) -{ - unsigned long result; - - __asm __volatile("bsrq %1,%0" - : "=r" (result) - : "rm" (mask)); - return result; -} - /** * * fls - Find the Last (most significant) bit Set in value and @@ -69,61 +47,98 @@ bsrq(unsigned long mask) * ... * fls (0x80000001) = 31 * - * @param mask: 'int' type value + * @param value: 'unsigned int' type value * - * @return value: zero-based bit index, -1 means 'mask' was zero. + * @return value: zero-based bit index, -1 means 'value' was zero. * * **/ -static inline int -fls(int mask) +static inline int fls(unsigned int value) { - return (mask == 0 ? -1 : (int)bsrl((unsigned int)mask)); + int ret; + + asm volatile("bsrl %1,%0" + : "=r" (ret) + : "rm" (value), "0" (-1)); + return ret; } -/* 64bit version of fls(). */ -static inline int -flsl(long mask) +static inline int fls64(unsigned long value) { - return (mask == 0 ? -1 : (int)bsrq((unsigned long)mask)); -} + int ret; -static inline unsigned long -bsfq(unsigned long mask) -{ - unsigned long result; - - __asm __volatile("bsfq %1,%0" - : "=r" (result) - : "rm" (mask)); - return result; + asm volatile("bsrq %1,%q0" + : "=r" (ret) + : "rm" (value), "0" (-1)); + return ret; } /** * - * ffsl - Find the First (least significant) bit Set in value(Long type) + * ffs64 - Find the First (least significant) bit Set in value(Long type) * and return the index of that bit. * * Bits are numbered starting at 0,the least significant bit. * A return value of -1 means that the argument was zero. * * Examples: - * ffsl (0x0) = -1 - * ffsl (0x01) = 0 - * ffsl (0xf0) = 4 - * ffsl (0xf00) = 8 + * ffs64 (0x0) = -1 + * ffs64 (0x01) = 0 + * ffs64 (0xf0) = 4 + * ffs64 (0xf00) = 8 * ... - * ffsl (0x8000000000000001) = 0 - * ffsl (0xf000000000000000) = 60 + * ffs64 (0x8000000000000001) = 0 + * ffs64 (0xf000000000000000) = 60 * - * @param mask: 'long' type value + * @param value: 'unsigned long' type value * - * @return value: zero-based bit index, -1 means 'mask' was zero. + * @return value: zero-based bit index, -1 means 'value' was zero. * * **/ -static inline int -ffsl(long mask) +static inline int ffs64(unsigned long value) { - return (mask == 0 ? -1 : (int)bsfq((unsigned long)mask)); + int ret; + asm volatile("bsfq %1,%q0" + : "=r" (ret) + : "rm" (value), "0" (-1)); + return ret; +} + +/*bit scan forward for the least significant bit '0'*/ +static inline int ffz64(unsigned long value) +{ + return ffs64(~value); +} + +/** + * Counts leading zeros. + * + * The number of leading zeros is defined as the number of + * most significant bits which are not '1'. E.g.: + * clz(0x80000000)==0 + * clz(0x40000000)==1 + * ... + * clz(0x00000001)==31 + * clz(0x00000000)==32 + * + * @param value:The 32 bit value to count the number of leading zeros. + * + * @return The number of leading zeros in 'value'. + */ +static inline int clz(unsigned int value) +{ + return (31 - fls(value)); +} + +/** + * Counts leading zeros (64 bit version). + * + * @param value:The 64 bit value to count the number of leading zeros. + * + * @return The number of leading zeros in 'value'. + */ +static inline int clz64(unsigned long value) +{ + return (63 - fls64(value)); } static inline void @@ -190,51 +205,4 @@ bitmap_test_and_clear(int mask, unsigned long *bits) return (!!ret); } -static inline int -bitmap_ffs(unsigned long *bits) -{ - return ffsl(*bits); -} - -/*bit scan forward for the least significant bit '0'*/ -static inline int -get_first_zero_bit(unsigned long value) -{ - return ffsl(~value); -} - -/** - * Counts leading zeros. - * - * The number of leading zeros is defined as the number of - * most significant bits which are not '1'. E.g.: - * clz(0x80000000)==0 - * clz(0x40000000)==1 - * ... - * clz(0x00000001)==31 - * clz(0x00000000)==32 - * - * @param mask:The 32 bit value to count the number of leading zeros. - * - * @return The number of leading zeros in 'mask'. - */ -static inline int -clz(int mask) -{ - return (31 - fls(mask)); -} - -/** - * Counts leading zeros (64 bit version). - * - * @param mask:The 64 bit value to count the number of leading zeros. - * - * @return The number of leading zeros in 'mask'. - */ -static inline int -clz64(long mask) -{ - return (63 - flsl(mask)); -} - #endif /* BITS_H*/ diff --git a/hypervisor/lib/memory.c b/hypervisor/lib/memory.c index f3cb3d7c5..3230ddb10 100644 --- a/hypervisor/lib/memory.c +++ b/hypervisor/lib/memory.c @@ -81,7 +81,7 @@ static void *allocate_mem(struct mem_pool *pool, unsigned int num_bytes) /* Find the first occurrence of requested_buffs number of free * buffers. The 0th bit in bitmap represents a free buffer. */ - for (bit_idx = get_first_zero_bit(pool->bitmap[idx]); + for (bit_idx = ffz64(pool->bitmap[idx]); bit_idx < BITMAP_WORD_SIZE; bit_idx++) { /* Check if selected buffer is free */ if (pool->bitmap[idx] & (1 << bit_idx))