aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/lapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r--arch/x86/kvm/lapic.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 943acbf00c69..e2c1fb8d35ce 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -266,9 +266,14 @@ static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id)
266 recalculate_apic_map(apic->vcpu->kvm); 266 recalculate_apic_map(apic->vcpu->kvm);
267} 267}
268 268
269static inline u32 kvm_apic_calc_x2apic_ldr(u32 id)
270{
271 return ((id >> 4) << 16) | (1 << (id & 0xf));
272}
273
269static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id) 274static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id)
270{ 275{
271 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); 276 u32 ldr = kvm_apic_calc_x2apic_ldr(id);
272 277
273 WARN_ON_ONCE(id != apic->vcpu->vcpu_id); 278 WARN_ON_ONCE(id != apic->vcpu->vcpu_id);
274 279
@@ -2245,6 +2250,7 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
2245{ 2250{
2246 if (apic_x2apic_mode(vcpu->arch.apic)) { 2251 if (apic_x2apic_mode(vcpu->arch.apic)) {
2247 u32 *id = (u32 *)(s->regs + APIC_ID); 2252 u32 *id = (u32 *)(s->regs + APIC_ID);
2253 u32 *ldr = (u32 *)(s->regs + APIC_LDR);
2248 2254
2249 if (vcpu->kvm->arch.x2apic_format) { 2255 if (vcpu->kvm->arch.x2apic_format) {
2250 if (*id != vcpu->vcpu_id) 2256 if (*id != vcpu->vcpu_id)
@@ -2255,6 +2261,10 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
2255 else 2261 else
2256 *id <<= 24; 2262 *id <<= 24;
2257 } 2263 }
2264
2265 /* In x2APIC mode, the LDR is fixed and based on the id */
2266 if (set)
2267 *ldr = kvm_apic_calc_x2apic_ldr(*id);
2258 } 2268 }
2259 2269
2260 return 0; 2270 return 0;