diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
| -rw-r--r-- | arch/x86/kvm/lapic.c | 27 | 
1 files changed, 23 insertions, 4 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index f1bdac3f5aa8..0e68b4c937fc 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)  	}  } +static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic) +{ +	struct kvm *kvm = apic->vcpu->kvm; + +	if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm)) +		return; + +	if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id) +		return; + +	kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); +} +  static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)  {  	int ret = 0; @@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)  	switch (reg) {  	case APIC_ID:		/* Local APIC ID */ -		if (!apic_x2apic_mode(apic)) +		if (!apic_x2apic_mode(apic)) {  			kvm_apic_set_xapic_id(apic, val >> 24); -		else +			kvm_lapic_xapic_id_updated(apic); +		} else {  			ret = 1; +		}  		break;  	case APIC_TASKPRI: @@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)  			     MSR_IA32_APICBASE_BASE;  	if ((value & MSR_IA32_APICBASE_ENABLE) && -	     apic->base_address != APIC_DEFAULT_PHYS_BASE) -		pr_warn_once("APIC base relocation is unsupported by KVM"); +	     apic->base_address != APIC_DEFAULT_PHYS_BASE) { +		kvm_set_apicv_inhibit(apic->vcpu->kvm, +				      APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); +	}  }  void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) @@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,  			icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);  			__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);  		} +	} else { +		kvm_lapic_xapic_id_updated(vcpu->arch.apic);  	}  	return 0;  | 
