aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/lapic.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 07ad628dadb..6f9fd633c88 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -66,6 +66,7 @@
66#define APIC_DEST_NOSHORT 0x0 66#define APIC_DEST_NOSHORT 0x0
67#define APIC_DEST_MASK 0x800 67#define APIC_DEST_MASK 0x800
68#define MAX_APIC_VECTOR 256 68#define MAX_APIC_VECTOR 256
69#define APIC_VECTORS_PER_REG 32
69 70
70#define VEC_POS(v) ((v) & (32 - 1)) 71#define VEC_POS(v) ((v) & (32 - 1))
71#define REG_POS(v) (((v) >> 5) << 4) 72#define REG_POS(v) (((v) >> 5) << 4)
@@ -208,25 +209,30 @@ static const unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
208 209
209static int find_highest_vector(void *bitmap) 210static int find_highest_vector(void *bitmap)
210{ 211{
211 u32 *word = bitmap; 212 int vec;
212 int word_offset = MAX_APIC_VECTOR >> 5; 213 u32 *reg;
213 214
214 while ((word_offset != 0) && (word[(--word_offset) << 2] == 0)) 215 for (vec = MAX_APIC_VECTOR - APIC_VECTORS_PER_REG;
215 continue; 216 vec >= 0; vec -= APIC_VECTORS_PER_REG) {
217 reg = bitmap + REG_POS(vec);
218 if (*reg)
219 return fls(*reg) - 1 + vec;
220 }
216 221
217 if (likely(!word_offset && !word[0])) 222 return -1;
218 return -1;
219 else
220 return fls(word[word_offset << 2]) - 1 + (word_offset << 5);
221} 223}
222 224
223static u8 count_vectors(void *bitmap) 225static u8 count_vectors(void *bitmap)
224{ 226{
225 u32 *word = bitmap; 227 int vec;
226 int word_offset; 228 u32 *reg;
227 u8 count = 0; 229 u8 count = 0;
228 for (word_offset = 0; word_offset < MAX_APIC_VECTOR >> 5; ++word_offset) 230
229 count += hweight32(word[word_offset << 2]); 231 for (vec = 0; vec < MAX_APIC_VECTOR; vec += APIC_VECTORS_PER_REG) {
232 reg = bitmap + REG_POS(vec);
233 count += hweight32(*reg);
234 }
235
230 return count; 236 return count;
231} 237}
232 238