diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
| -rw-r--r-- | arch/x86/kvm/lapic.c | 65 | 
1 files changed, 30 insertions, 35 deletions
| diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 759952dd1222..c5028e6b0f96 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -185,7 +185,7 @@ void kvm_recalculate_apic_map(struct kvm *kvm)  {  	struct kvm_apic_map *new, *old = NULL;  	struct kvm_vcpu *vcpu; -	int i; +	unsigned long i;  	u32 max_id = 255; /* enough space for any xAPIC ID */  	/* Read kvm->arch.apic_map_dirty before kvm->arch.apic_map.  */ @@ -673,41 +673,40 @@ static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu)  	return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED;  } -static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) -{ -	u8 val; -	if (pv_eoi_get_user(vcpu, &val) < 0) { -		printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n", -			   (unsigned long long)vcpu->arch.pv_eoi.msr_val); -		return false; -	} -	return val & KVM_PV_EOI_ENABLED; -} -  static void pv_eoi_set_pending(struct kvm_vcpu *vcpu)  { -	if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { -		printk(KERN_WARNING "Can't set EOI MSR value: 0x%llx\n", -			   (unsigned long long)vcpu->arch.pv_eoi.msr_val); +	if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0)  		return; -	} +  	__set_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);  } -static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) +static bool pv_eoi_test_and_clr_pending(struct kvm_vcpu *vcpu)  { -	if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { -		printk(KERN_WARNING "Can't clear EOI MSR value: 0x%llx\n", -			   (unsigned long long)vcpu->arch.pv_eoi.msr_val); -		return; -	} +	u8 val; + +	if (pv_eoi_get_user(vcpu, &val) < 0) +		return false; + +	val &= KVM_PV_EOI_ENABLED; + +	if (val && pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) +		return false; + +	/* +	 * Clear pending bit in any case: it will be set again on vmentry. +	 * While this might not be ideal from performance point of view, +	 * this makes sure pv eoi is only enabled when we know it's safe. +	 */  	__clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); + +	return val;  }  static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr)  {  	int highest_irr; -	if (apic->vcpu->arch.apicv_active) +	if (kvm_x86_ops.sync_pir_to_irr)  		highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu);  	else  		highest_irr = apic_find_highest_irr(apic); @@ -1101,6 +1100,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,  			kvm_lapic_set_irr(vector, apic);  			kvm_make_request(KVM_REQ_EVENT, vcpu);  			kvm_vcpu_kick(vcpu); +		} else { +			trace_kvm_apicv_accept_irq(vcpu->vcpu_id, delivery_mode, +						   trig_mode, vector);  		}  		break; @@ -1172,8 +1174,8 @@ void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq,  	struct kvm_lapic *src = NULL;  	struct kvm_apic_map *map;  	struct kvm_vcpu *vcpu; -	unsigned long bitmap; -	int i, vcpu_idx; +	unsigned long bitmap, i; +	int vcpu_idx;  	bool ret;  	rcu_read_lock(); @@ -1931,7 +1933,7 @@ void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu)  	/* If the preempt notifier has already run, it also called apic_timer_expired */  	if (!apic->lapic_timer.hv_timer_in_use)  		goto out; -	WARN_ON(rcuwait_active(&vcpu->wait)); +	WARN_ON(kvm_vcpu_is_blocking(vcpu));  	apic_timer_expired(apic, false);  	cancel_hv_timer(apic); @@ -2677,7 +2679,6 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)  static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu,  					struct kvm_lapic *apic)  { -	bool pending;  	int vector;  	/*  	 * PV EOI state is derived from KVM_APIC_PV_EOI_PENDING in host @@ -2691,14 +2692,8 @@ static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu,  	 * 	-> host enabled PV EOI, guest executed EOI.  	 */  	BUG_ON(!pv_eoi_enabled(vcpu)); -	pending = pv_eoi_get_pending(vcpu); -	/* -	 * Clear pending bit in any case: it will be set again on vmentry. -	 * While this might not be ideal from performance point of view, -	 * this makes sure pv eoi is only enabled when we know it's safe. -	 */ -	pv_eoi_clr_pending(vcpu); -	if (pending) + +	if (pv_eoi_test_and_clr_pending(vcpu))  		return;  	vector = apic_set_eoi(apic);  	trace_kvm_pv_eoi(apic, vector); |