diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 07ad628dadb7..6f9fd633c888 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 | ||
209 | static int find_highest_vector(void *bitmap) | 210 | static 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 | ||
223 | static u8 count_vectors(void *bitmap) | 225 | static 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 | ||