diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
| -rw-r--r-- | arch/x86/kvm/lapic.c | 12 | 
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)  	recalculate_apic_map(apic->vcpu->kvm);  } +static inline u32 kvm_apic_calc_x2apic_ldr(u32 id) +{ +	return ((id >> 4) << 16) | (1 << (id & 0xf)); +} +  static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id)  { -	u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); +	u32 ldr = kvm_apic_calc_x2apic_ldr(id);  	WARN_ON_ONCE(id != apic->vcpu->vcpu_id); @@ -2245,6 +2250,7 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,  {  	if (apic_x2apic_mode(vcpu->arch.apic)) {  		u32 *id = (u32 *)(s->regs + APIC_ID); +		u32 *ldr = (u32 *)(s->regs + APIC_LDR);  		if (vcpu->kvm->arch.x2apic_format) {  			if (*id != vcpu->vcpu_id) @@ -2255,6 +2261,10 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,  			else  				*id <<= 24;  		} + +		/* In x2APIC mode, the LDR is fixed and based on the id */ +		if (set) +			*ldr = kvm_apic_calc_x2apic_ldr(*id);  	}  	return 0; |