diff mbox

KVM: Set TMR when programming ioapic entry

Message ID 1363606942-5600-1-git-send-email-yang.z.zhang@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zhang, Yang Z March 18, 2013, 11:42 a.m. UTC
From: Yang Zhang <yang.z.zhang@Intel.com>

We already know the trigger mode of a given interrupt when programming
the ioapice entry. So it's not necessary to set it in each interrupt
delivery.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 arch/x86/kvm/lapic.c     |   26 ++++++++++++++------------
 arch/x86/kvm/lapic.h     |    5 ++---
 arch/x86/kvm/vmx.c       |    2 ++
 arch/x86/kvm/x86.c       |   12 ++++++++----
 include/linux/kvm_host.h |    4 ++--
 virt/kvm/ioapic.c        |   17 +++++++++--------
 virt/kvm/ioapic.h        |    5 ++---
 virt/kvm/kvm_main.c      |    4 ++--
 8 files changed, 41 insertions(+), 34 deletions(-)

Comments

Gleb Natapov March 18, 2013, 12:28 p.m. UTC | #1
On Mon, Mar 18, 2013 at 07:42:22PM +0800, Yang Zhang wrote:
> From: Yang Zhang <yang.z.zhang@Intel.com>
> 
> We already know the trigger mode of a given interrupt when programming
> the ioapice entry. So it's not necessary to set it in each interrupt
> delivery.
> 
What this patch suppose to go on top of?

> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
> ---
>  arch/x86/kvm/lapic.c     |   26 ++++++++++++++------------
>  arch/x86/kvm/lapic.h     |    5 ++---
>  arch/x86/kvm/vmx.c       |    2 ++
>  arch/x86/kvm/x86.c       |   12 ++++++++----
>  include/linux/kvm_host.h |    4 ++--
>  virt/kvm/ioapic.c        |   17 +++++++++--------
>  virt/kvm/ioapic.h        |    5 ++---
>  virt/kvm/kvm_main.c      |    4 ++--
>  8 files changed, 41 insertions(+), 34 deletions(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index d0b553b..0d2bcde 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -194,18 +194,17 @@ out:
>  	rcu_read_unlock();
>  }
>  
> -void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
> -				struct kvm_lapic_irq *irq,
> -				u64 *eoi_exit_bitmap)
> +bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu,	struct kvm_lapic_irq *irq)
>  {
>  	DECLARE_BITMAP(vcpu_map, KVM_MAX_VCPUS);
>  
>  	memset(vcpu_map, 0, sizeof(vcpu_map));
>  
>  	kvm_get_dest_vcpu(vcpu->kvm, irq, vcpu_map);
> -	if (test_bit(vcpu->vcpu_id, vcpu_map) ||
> -			bitmap_empty(vcpu_map, sizeof(vcpu_map)))
> -		__set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap);
> +	if (test_bit(vcpu->vcpu_id, vcpu_map))
> +		return true;
> +
> +	return false;
>  }
>  
>  static void recalculate_apic_map(struct kvm *kvm)
> @@ -534,6 +533,15 @@ static inline int apic_find_highest_isr(struct kvm_lapic *apic)
>  	return result;
>  }
>  
> +void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
> +{
> +	struct kvm_lapic *apic = vcpu->arch.apic;
> +	int i;
> +
> +	for (i = 0; i < 8; i++)
> +		apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
> +}
> +
>  static void apic_update_ppr(struct kvm_lapic *apic)
>  {
>  	u32 tpr, isrv, ppr, old_ppr;
> @@ -723,12 +731,6 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
>  		if (unlikely(!apic_enabled(apic)))
>  			break;
>  
> -		if (trig_mode) {
> -			apic_debug("level trig mode for vector %d", vector);
> -			apic_set_vector(vector, apic->regs + APIC_TMR);
> -		} else
> -			apic_clear_vector(vector, apic->regs + APIC_TMR);
> -
>  		result = 1;
>  		if (!kvm_x86_ops->deliver_posted_interrupt(vcpu, vector))
>  			result = !apic_test_and_set_irr(vector, apic);
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index 4d38836..7e8d35f 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -48,6 +48,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
>  u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
>  void kvm_apic_set_version(struct kvm_vcpu *vcpu);
>  
> +void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr);
>  int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
>  int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
>  int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
> @@ -155,9 +156,7 @@ static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr)
>  	return ldr & map->lid_mask;
>  }
>  
> -void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
> -				struct kvm_lapic_irq *irq,
> -				u64 *eoi_bitmap);
> +bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
>  void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
>  
>  void kvm_get_dest_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 1985849..1571df2 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6486,6 +6486,8 @@ static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
>  
>  static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
>  {
> +	if (!vmx_vm_has_apicv(vcpu->kvm))
> +		return;
>  	vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
>  	vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]);
>  	vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 1f54987..5b88c2c 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5632,13 +5632,17 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
>  #endif
>  }
>  
> -static void update_eoi_exitmap(struct kvm_vcpu *vcpu)
> +static void update_intr_bitmap(struct kvm_vcpu *vcpu)
>  {
>  	u64 eoi_exit_bitmap[4];
> +	u64 tmr[4];
>  
>  	memset(eoi_exit_bitmap, 0, 32);
> +	memset(tmr, 0, 32);
>  
> -	kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap);
> +	kvm_ioapic_get_intr_map(vcpu, (unsigned long *)tmr,
> +				(unsigned long *)eoi_exit_bitmap);
> +	kvm_apic_update_tmr(vcpu, (u32 *)tmr);
>  	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
>  }
>  
> @@ -5695,8 +5699,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  			kvm_handle_pmu_event(vcpu);
>  		if (kvm_check_request(KVM_REQ_PMI, vcpu))
>  			kvm_deliver_pmi(vcpu);
> -		if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu))
> -			update_eoi_exitmap(vcpu);
> +		if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
> +			update_intr_bitmap(vcpu);
>  	}
>  
>  	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 722cae7..9fe6433 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -123,7 +123,7 @@ static inline bool is_error_page(struct page *page)
>  #define KVM_REQ_MASTERCLOCK_UPDATE 19
>  #define KVM_REQ_MCLOCK_INPROGRESS 20
>  #define KVM_REQ_EPR_EXIT          21
> -#define KVM_REQ_EOIBITMAP         22
> +#define KVM_REQ_SCAN_IOAPIC       22
>  
>  #define KVM_USERSPACE_IRQ_SOURCE_ID		0
>  #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1
> @@ -538,7 +538,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
>  void kvm_flush_remote_tlbs(struct kvm *kvm);
>  void kvm_reload_remote_mmus(struct kvm *kvm);
>  void kvm_make_mclock_inprogress_request(struct kvm *kvm);
> -void kvm_make_update_eoibitmap_request(struct kvm *kvm);
> +void kvm_make_scan_ioapic_request(struct kvm *kvm);
>  
>  long kvm_arch_dev_ioctl(struct file *filp,
>  			unsigned int ioctl, unsigned long arg);
> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
> index 8d498e5..8dae5a0 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -235,8 +235,8 @@ static void update_handled_vectors(struct kvm_ioapic *ioapic)
>  	smp_wmb();
>  }
>  
> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
> -					u64 *eoi_exit_bitmap)
> +void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
> +					unsigned long *eoi_exit_bitmap)
>  {
>  	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
>  	union kvm_ioapic_redirect_entry *e;
> @@ -244,7 +244,6 @@ void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>  	int index;
>  
>  	spin_lock(&ioapic->lock);
> -	/* traverse ioapic entry to set eoi exit bitmap*/
>  	for (index = 0; index < IOAPIC_NUM_PINS; index++) {
>  		e = &ioapic->redirtbl[index];
>  		if (!e->fields.mask &&
> @@ -255,12 +254,16 @@ void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>  			irqe.vector = e->fields.vector;
>  			irqe.dest_mode = e->fields.dest_mode;
>  			irqe.delivery_mode = e->fields.delivery_mode << 8;
> -			kvm_calculate_eoi_exitmap(vcpu, &irqe, eoi_exit_bitmap);
> +
> +			if (kvm_vcpu_match_dest(vcpu, &irqe)) {
> +				if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
> +					set_bit(irqe.vector, tmr);
> +				set_bit(irqe.vector, eoi_exit_bitmap);
> +			}
>  		}
>  	}
>  	spin_unlock(&ioapic->lock);
>  }
> -EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap);
>  
>  void kvm_scan_ioapic_entry(struct kvm *kvm)
>  {
> @@ -270,9 +273,7 @@ void kvm_scan_ioapic_entry(struct kvm *kvm)
>  		return;
>  
>  	rtc_irq_get_dest_vcpu(ioapic, 8);
> -
> -	if (kvm_apic_vid_enabled(kvm))
> -		kvm_make_update_eoibitmap_request(kvm);
> +	kvm_make_scan_ioapic_request(kvm);
>  }
>  
>  static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
> diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
> index 4904ca3..1997dfd 100644
> --- a/virt/kvm/ioapic.h
> +++ b/virt/kvm/ioapic.h
> @@ -93,8 +93,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
>  int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
>  int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
>  void kvm_scan_ioapic_entry(struct kvm *kvm);
> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
> -					u64 *eoi_exit_bitmap);
> -
> +void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
> +					unsigned long *eoi_exit_bitmap);
>  
>  #endif
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index cd73e0e..cf978c3 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -217,9 +217,9 @@ void kvm_make_mclock_inprogress_request(struct kvm *kvm)
>  	make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
>  }
>  
> -void kvm_make_update_eoibitmap_request(struct kvm *kvm)
> +void kvm_make_scan_ioapic_request(struct kvm *kvm)
>  {
> -	make_all_cpus_request(kvm, KVM_REQ_EOIBITMAP);
> +	make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
>  }
>  
>  int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
> -- 
> 1.7.1

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhang, Yang Z March 18, 2013, 12:32 p.m. UTC | #2
Gleb Natapov wrote on 2013-03-18:
> On Mon, Mar 18, 2013 at 07:42:22PM +0800, Yang Zhang wrote:
>> From: Yang Zhang <yang.z.zhang@Intel.com>
>> 
>> We already know the trigger mode of a given interrupt when programming
>> the ioapice entry. So it's not necessary to set it in each interrupt
>> delivery.
>> 
> What this patch suppose to go on top of?
Sorry, forget to mention it.
This is based on RTC patch(Use eoi to track RTC interrupt delivery status) and Posted interrupt patch(KVM: VMX: Add Posted Interrupt supporting).

>> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
>> ---
>>  arch/x86/kvm/lapic.c     |   26 ++++++++++++++------------
>>  arch/x86/kvm/lapic.h     |    5 ++---
>>  arch/x86/kvm/vmx.c       |    2 ++
>>  arch/x86/kvm/x86.c       |   12 ++++++++----
>>  include/linux/kvm_host.h |    4 ++--
>>  virt/kvm/ioapic.c        |   17 +++++++++--------
>>  virt/kvm/ioapic.h        |    5 ++---
>>  virt/kvm/kvm_main.c      |    4 ++--
>>  8 files changed, 41 insertions(+), 34 deletions(-)
>> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
>> index d0b553b..0d2bcde 100644
>> --- a/arch/x86/kvm/lapic.c
>> +++ b/arch/x86/kvm/lapic.c
>> @@ -194,18 +194,17 @@ out:
>>  	rcu_read_unlock();
>>  }
>> -void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>> -				struct kvm_lapic_irq *irq,
>> -				u64 *eoi_exit_bitmap)
>> +bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu,	struct kvm_lapic_irq
> *irq)
>>  {
>>  	DECLARE_BITMAP(vcpu_map, KVM_MAX_VCPUS);
>>  
>>  	memset(vcpu_map, 0, sizeof(vcpu_map));
>>  
>>  	kvm_get_dest_vcpu(vcpu->kvm, irq, vcpu_map);
>> -	if (test_bit(vcpu->vcpu_id, vcpu_map) ||
>> -			bitmap_empty(vcpu_map, sizeof(vcpu_map)))
>> -		__set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap);
>> +	if (test_bit(vcpu->vcpu_id, vcpu_map))
>> +		return true;
>> +
>> +	return false;
>>  }
>>  
>>  static void recalculate_apic_map(struct kvm *kvm)
>> @@ -534,6 +533,15 @@ static inline int apic_find_highest_isr(struct kvm_lapic
> *apic)
>>  	return result;
>>  }
>> +void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
>> +{
>> +	struct kvm_lapic *apic = vcpu->arch.apic;
>> +	int i;
>> +
>> +	for (i = 0; i < 8; i++)
>> +		apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
>> +}
>> +
>>  static void apic_update_ppr(struct kvm_lapic *apic)
>>  {
>>  	u32 tpr, isrv, ppr, old_ppr;
>> @@ -723,12 +731,6 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int
> delivery_mode,
>>  		if (unlikely(!apic_enabled(apic)))
>>  			break;
>> -		if (trig_mode) {
>> -			apic_debug("level trig mode for vector %d", vector);
>> -			apic_set_vector(vector, apic->regs + APIC_TMR);
>> -		} else
>> -			apic_clear_vector(vector, apic->regs + APIC_TMR);
>> -
>>  		result = 1;
>>  		if (!kvm_x86_ops->deliver_posted_interrupt(vcpu, vector))
>>  			result = !apic_test_and_set_irr(vector, apic);
>> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
>> index 4d38836..7e8d35f 100644
>> --- a/arch/x86/kvm/lapic.h
>> +++ b/arch/x86/kvm/lapic.h
>> @@ -48,6 +48,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64
> value);
>>  u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
>>  void kvm_apic_set_version(struct kvm_vcpu *vcpu);
>> +void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr);
>>  int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
>>  int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
>>  int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
>> @@ -155,9 +156,7 @@ static inline u16 apic_logical_id(struct kvm_apic_map
> *map, u32 ldr)
>>  	return ldr & map->lid_mask;
>>  }
>> -void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>> -				struct kvm_lapic_irq *irq,
>> -				u64 *eoi_bitmap);
>> +bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic_irq
> *irq);
>>  void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
>>  
>>  void kvm_get_dest_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index
>> 1985849..1571df2 100644 --- a/arch/x86/kvm/vmx.c +++
>> b/arch/x86/kvm/vmx.c @@ -6486,6 +6486,8 @@ static void
>> vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
>> 
>>  static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64
>>  *eoi_exit_bitmap) {
>> +	if (!vmx_vm_has_apicv(vcpu->kvm))
>> +		return;
>>  	vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
>>  	vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]);
>>  	vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]);
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 1f54987..5b88c2c 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -5632,13 +5632,17 @@ static void kvm_gen_update_masterclock(struct
> kvm *kvm)
>>  #endif
>>  }
>> -static void update_eoi_exitmap(struct kvm_vcpu *vcpu)
>> +static void update_intr_bitmap(struct kvm_vcpu *vcpu)
>>  {
>>  	u64 eoi_exit_bitmap[4];
>> +	u64 tmr[4];
>> 
>>  	memset(eoi_exit_bitmap, 0, 32);
>> +	memset(tmr, 0, 32);
>> 
>> -	kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap);
>> +	kvm_ioapic_get_intr_map(vcpu, (unsigned long *)tmr,
>> +				(unsigned long *)eoi_exit_bitmap);
>> +	kvm_apic_update_tmr(vcpu, (u32 *)tmr);
>>  	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
>>  }
>> @@ -5695,8 +5699,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>>  			kvm_handle_pmu_event(vcpu);
>>  		if (kvm_check_request(KVM_REQ_PMI, vcpu))
>>  			kvm_deliver_pmi(vcpu);
>> -		if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu))
>> -			update_eoi_exitmap(vcpu);
>> +		if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
>> +			update_intr_bitmap(vcpu);
>>  	}
>>  
>>  	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
>> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> index 722cae7..9fe6433 100644
>> --- a/include/linux/kvm_host.h
>> +++ b/include/linux/kvm_host.h
>> @@ -123,7 +123,7 @@ static inline bool is_error_page(struct page *page)
>>  #define KVM_REQ_MASTERCLOCK_UPDATE 19
>>  #define KVM_REQ_MCLOCK_INPROGRESS 20
>>  #define KVM_REQ_EPR_EXIT          21
>> -#define KVM_REQ_EOIBITMAP         22
>> +#define KVM_REQ_SCAN_IOAPIC       22
>> 
>>  #define KVM_USERSPACE_IRQ_SOURCE_ID		0 #define
>>  KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1 @@ -538,7 +538,7 @@ void
>>  kvm_put_guest_fpu(struct kvm_vcpu *vcpu); void
>>  kvm_flush_remote_tlbs(struct kvm *kvm); void
>>  kvm_reload_remote_mmus(struct kvm *kvm); void
>>  kvm_make_mclock_inprogress_request(struct kvm *kvm);
>> -void kvm_make_update_eoibitmap_request(struct kvm *kvm);
>> +void kvm_make_scan_ioapic_request(struct kvm *kvm);
>> 
>>  long kvm_arch_dev_ioctl(struct file *filp,
>>  			unsigned int ioctl, unsigned long arg);
>> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
>> index 8d498e5..8dae5a0 100644
>> --- a/virt/kvm/ioapic.c
>> +++ b/virt/kvm/ioapic.c
>> @@ -235,8 +235,8 @@ static void update_handled_vectors(struct kvm_ioapic
> *ioapic)
>>  	smp_wmb();
>>  }
>> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>> -					u64 *eoi_exit_bitmap)
>> +void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
>> +					unsigned long *eoi_exit_bitmap)
>>  {
>>  	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
>>  	union kvm_ioapic_redirect_entry *e;
>> @@ -244,7 +244,6 @@ void kvm_ioapic_calculate_eoi_exitmap(struct
> kvm_vcpu *vcpu,
>>  	int index;
>>  
>>  	spin_lock(&ioapic->lock); -	/* traverse ioapic entry to set eoi exit
>>  bitmap*/ 	for (index = 0; index < IOAPIC_NUM_PINS; index++) { 		e =
>>  &ioapic->redirtbl[index]; 		if (!e->fields.mask &&
>> @@ -255,12 +254,16 @@ void kvm_ioapic_calculate_eoi_exitmap(struct
> kvm_vcpu *vcpu,
>>  			irqe.vector = e->fields.vector;
>>  			irqe.dest_mode = e->fields.dest_mode;
>>  			irqe.delivery_mode = e->fields.delivery_mode << 8;
>> -			kvm_calculate_eoi_exitmap(vcpu, &irqe, eoi_exit_bitmap);
>> +
>> +			if (kvm_vcpu_match_dest(vcpu, &irqe)) {
>> +				if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
>> +					set_bit(irqe.vector, tmr);
>> +				set_bit(irqe.vector, eoi_exit_bitmap);
>> +			}
>>  		}
>>  	}
>>  	spin_unlock(&ioapic->lock);
>>  }
>> -EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap);
>> 
>>  void kvm_scan_ioapic_entry(struct kvm *kvm) { @@ -270,9 +273,7 @@ void
>>  kvm_scan_ioapic_entry(struct kvm *kvm) 		return;
>>  
>>  	rtc_irq_get_dest_vcpu(ioapic, 8);
>> -
>> -	if (kvm_apic_vid_enabled(kvm))
>> -		kvm_make_update_eoibitmap_request(kvm);
>> +	kvm_make_scan_ioapic_request(kvm);
>>  }
>>  
>>  static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
>> diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
>> index 4904ca3..1997dfd 100644
>> --- a/virt/kvm/ioapic.h
>> +++ b/virt/kvm/ioapic.h
>> @@ -93,8 +93,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct
> kvm_lapic *src,
>>  int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
>>  int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
>>  void kvm_scan_ioapic_entry(struct kvm *kvm);
>> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
>> -					u64 *eoi_exit_bitmap);
>> -
>> +void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
>> +					unsigned long *eoi_exit_bitmap);
>> 
>>  #endif
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index cd73e0e..cf978c3 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -217,9 +217,9 @@ void kvm_make_mclock_inprogress_request(struct
> kvm *kvm)
>>  	make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
>>  }
>> -void kvm_make_update_eoibitmap_request(struct kvm *kvm)
>> +void kvm_make_scan_ioapic_request(struct kvm *kvm)
>>  {
>> -	make_all_cpus_request(kvm, KVM_REQ_EOIBITMAP);
>> +	make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
>>  }
>>  
>>  int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
>> --
>> 1.7.1
> 
> --
> 			Gleb.


Best regards,
Yang


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov March 18, 2013, 12:52 p.m. UTC | #3
On Mon, Mar 18, 2013 at 12:32:51PM +0000, Zhang, Yang Z wrote:
> Gleb Natapov wrote on 2013-03-18:
> > On Mon, Mar 18, 2013 at 07:42:22PM +0800, Yang Zhang wrote:
> >> From: Yang Zhang <yang.z.zhang@Intel.com>
> >> 
> >> We already know the trigger mode of a given interrupt when programming
> >> the ioapice entry. So it's not necessary to set it in each interrupt
> >> delivery.
> >> 
> > What this patch suppose to go on top of?
> Sorry, forget to mention it.
> This is based on RTC patch(Use eoi to track RTC interrupt delivery status) and Posted interrupt patch(KVM: VMX: Add Posted Interrupt supporting).
> 
Since it touches the code added by RTC patch series that will be changed
after my latest comments it is hard to review that.

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhang, Yang Z March 18, 2013, 1 p.m. UTC | #4
Gleb Natapov wrote on 2013-03-18:
> On Mon, Mar 18, 2013 at 12:32:51PM +0000, Zhang, Yang Z wrote:
>> Gleb Natapov wrote on 2013-03-18:
>>> On Mon, Mar 18, 2013 at 07:42:22PM +0800, Yang Zhang wrote:
>>>> From: Yang Zhang <yang.z.zhang@Intel.com>
>>>> 
>>>> We already know the trigger mode of a given interrupt when programming
>>>> the ioapice entry. So it's not necessary to set it in each interrupt
>>>> delivery.
>>>> 
>>> What this patch suppose to go on top of?
>> Sorry, forget to mention it. This is based on RTC patch(Use eoi to
>> track RTC interrupt delivery status) and Posted interrupt patch(KVM:
>> VMX: Add Posted Interrupt supporting).
>> 
> Since it touches the code added by RTC patch series that will be changed
> after my latest comments it is hard to review that.
I have send out the modified RTC patch. Please review it.

Best regards,
Yang


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index d0b553b..0d2bcde 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -194,18 +194,17 @@  out:
 	rcu_read_unlock();
 }
 
-void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
-				struct kvm_lapic_irq *irq,
-				u64 *eoi_exit_bitmap)
+bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu,	struct kvm_lapic_irq *irq)
 {
 	DECLARE_BITMAP(vcpu_map, KVM_MAX_VCPUS);
 
 	memset(vcpu_map, 0, sizeof(vcpu_map));
 
 	kvm_get_dest_vcpu(vcpu->kvm, irq, vcpu_map);
-	if (test_bit(vcpu->vcpu_id, vcpu_map) ||
-			bitmap_empty(vcpu_map, sizeof(vcpu_map)))
-		__set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap);
+	if (test_bit(vcpu->vcpu_id, vcpu_map))
+		return true;
+
+	return false;
 }
 
 static void recalculate_apic_map(struct kvm *kvm)
@@ -534,6 +533,15 @@  static inline int apic_find_highest_isr(struct kvm_lapic *apic)
 	return result;
 }
 
+void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
+}
+
 static void apic_update_ppr(struct kvm_lapic *apic)
 {
 	u32 tpr, isrv, ppr, old_ppr;
@@ -723,12 +731,6 @@  static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
 		if (unlikely(!apic_enabled(apic)))
 			break;
 
-		if (trig_mode) {
-			apic_debug("level trig mode for vector %d", vector);
-			apic_set_vector(vector, apic->regs + APIC_TMR);
-		} else
-			apic_clear_vector(vector, apic->regs + APIC_TMR);
-
 		result = 1;
 		if (!kvm_x86_ops->deliver_posted_interrupt(vcpu, vector))
 			result = !apic_test_and_set_irr(vector, apic);
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 4d38836..7e8d35f 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -48,6 +48,7 @@  void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
 u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
 void kvm_apic_set_version(struct kvm_vcpu *vcpu);
 
+void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr);
 int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
 int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
 int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
@@ -155,9 +156,7 @@  static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr)
 	return ldr & map->lid_mask;
 }
 
-void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
-				struct kvm_lapic_irq *irq,
-				u64 *eoi_bitmap);
+bool kvm_vcpu_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
 void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
 
 void kvm_get_dest_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 1985849..1571df2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6486,6 +6486,8 @@  static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
 
 static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
 {
+	if (!vmx_vm_has_apicv(vcpu->kvm))
+		return;
 	vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
 	vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]);
 	vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1f54987..5b88c2c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5632,13 +5632,17 @@  static void kvm_gen_update_masterclock(struct kvm *kvm)
 #endif
 }
 
-static void update_eoi_exitmap(struct kvm_vcpu *vcpu)
+static void update_intr_bitmap(struct kvm_vcpu *vcpu)
 {
 	u64 eoi_exit_bitmap[4];
+	u64 tmr[4];
 
 	memset(eoi_exit_bitmap, 0, 32);
+	memset(tmr, 0, 32);
 
-	kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap);
+	kvm_ioapic_get_intr_map(vcpu, (unsigned long *)tmr,
+				(unsigned long *)eoi_exit_bitmap);
+	kvm_apic_update_tmr(vcpu, (u32 *)tmr);
 	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
@@ -5695,8 +5699,8 @@  static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			kvm_handle_pmu_event(vcpu);
 		if (kvm_check_request(KVM_REQ_PMI, vcpu))
 			kvm_deliver_pmi(vcpu);
-		if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu))
-			update_eoi_exitmap(vcpu);
+		if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
+			update_intr_bitmap(vcpu);
 	}
 
 	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 722cae7..9fe6433 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -123,7 +123,7 @@  static inline bool is_error_page(struct page *page)
 #define KVM_REQ_MASTERCLOCK_UPDATE 19
 #define KVM_REQ_MCLOCK_INPROGRESS 20
 #define KVM_REQ_EPR_EXIT          21
-#define KVM_REQ_EOIBITMAP         22
+#define KVM_REQ_SCAN_IOAPIC       22
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID		0
 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID	1
@@ -538,7 +538,7 @@  void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
 void kvm_flush_remote_tlbs(struct kvm *kvm);
 void kvm_reload_remote_mmus(struct kvm *kvm);
 void kvm_make_mclock_inprogress_request(struct kvm *kvm);
-void kvm_make_update_eoibitmap_request(struct kvm *kvm);
+void kvm_make_scan_ioapic_request(struct kvm *kvm);
 
 long kvm_arch_dev_ioctl(struct file *filp,
 			unsigned int ioctl, unsigned long arg);
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 8d498e5..8dae5a0 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -235,8 +235,8 @@  static void update_handled_vectors(struct kvm_ioapic *ioapic)
 	smp_wmb();
 }
 
-void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
-					u64 *eoi_exit_bitmap)
+void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
+					unsigned long *eoi_exit_bitmap)
 {
 	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
 	union kvm_ioapic_redirect_entry *e;
@@ -244,7 +244,6 @@  void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
 	int index;
 
 	spin_lock(&ioapic->lock);
-	/* traverse ioapic entry to set eoi exit bitmap*/
 	for (index = 0; index < IOAPIC_NUM_PINS; index++) {
 		e = &ioapic->redirtbl[index];
 		if (!e->fields.mask &&
@@ -255,12 +254,16 @@  void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
 			irqe.vector = e->fields.vector;
 			irqe.dest_mode = e->fields.dest_mode;
 			irqe.delivery_mode = e->fields.delivery_mode << 8;
-			kvm_calculate_eoi_exitmap(vcpu, &irqe, eoi_exit_bitmap);
+
+			if (kvm_vcpu_match_dest(vcpu, &irqe)) {
+				if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
+					set_bit(irqe.vector, tmr);
+				set_bit(irqe.vector, eoi_exit_bitmap);
+			}
 		}
 	}
 	spin_unlock(&ioapic->lock);
 }
-EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap);
 
 void kvm_scan_ioapic_entry(struct kvm *kvm)
 {
@@ -270,9 +273,7 @@  void kvm_scan_ioapic_entry(struct kvm *kvm)
 		return;
 
 	rtc_irq_get_dest_vcpu(ioapic, 8);
-
-	if (kvm_apic_vid_enabled(kvm))
-		kvm_make_update_eoibitmap_request(kvm);
+	kvm_make_scan_ioapic_request(kvm);
 }
 
 static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 4904ca3..1997dfd 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -93,8 +93,7 @@  int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
 int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
 void kvm_scan_ioapic_entry(struct kvm *kvm);
-void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
-					u64 *eoi_exit_bitmap);
-
+void kvm_ioapic_get_intr_map(struct kvm_vcpu *vcpu, unsigned long *tmr,
+					unsigned long *eoi_exit_bitmap);
 
 #endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cd73e0e..cf978c3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -217,9 +217,9 @@  void kvm_make_mclock_inprogress_request(struct kvm *kvm)
 	make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
 }
 
-void kvm_make_update_eoibitmap_request(struct kvm *kvm)
+void kvm_make_scan_ioapic_request(struct kvm *kvm)
 {
-	make_all_cpus_request(kvm, KVM_REQ_EOIBITMAP);
+	make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
 }
 
 int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)