diff options
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 2eec05b6d1b8..11544d8f1e97 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -383,20 +383,25 @@ static inline int eilvt_entry_is_changeable(unsigned int old, unsigned int new) | |||
383 | 383 | ||
384 | static unsigned int reserve_eilvt_offset(int offset, unsigned int new) | 384 | static unsigned int reserve_eilvt_offset(int offset, unsigned int new) |
385 | { | 385 | { |
386 | unsigned int rsvd; /* 0: uninitialized */ | 386 | unsigned int rsvd, vector; |
387 | 387 | ||
388 | if (offset >= APIC_EILVT_NR_MAX) | 388 | if (offset >= APIC_EILVT_NR_MAX) |
389 | return ~0; | 389 | return ~0; |
390 | 390 | ||
391 | rsvd = atomic_read(&eilvt_offsets[offset]) & ~APIC_EILVT_MASKED; | 391 | rsvd = atomic_read(&eilvt_offsets[offset]); |
392 | do { | 392 | do { |
393 | if (rsvd && | 393 | vector = rsvd & ~APIC_EILVT_MASKED; /* 0: unassigned */ |
394 | !eilvt_entry_is_changeable(rsvd, new)) | 394 | if (vector && !eilvt_entry_is_changeable(vector, new)) |
395 | /* may not change if vectors are different */ | 395 | /* may not change if vectors are different */ |
396 | return rsvd; | 396 | return rsvd; |
397 | rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new); | 397 | rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new); |
398 | } while (rsvd != new); | 398 | } while (rsvd != new); |
399 | 399 | ||
400 | rsvd &= ~APIC_EILVT_MASKED; | ||
401 | if (rsvd && rsvd != vector) | ||
402 | pr_info("LVT offset %d assigned for vector 0x%02x\n", | ||
403 | offset, rsvd); | ||
404 | |||
400 | return new; | 405 | return new; |
401 | } | 406 | } |
402 | 407 | ||