35
35
#include "kvm_cache_regs.h"
36
36
#include "irq.h"
37
37
#include "trace.h"
38
+ #include "x86.h"
38
39
39
40
#ifndef CONFIG_X86_64
40
41
#define mod_64 (x , y ) ((x) - (y) * div64_u64(x, y))
@@ -142,6 +143,21 @@ static inline int apic_lvt_nmi_mode(u32 lvt_val)
142
143
return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED )) == APIC_DM_NMI ;
143
144
}
144
145
146
+ void kvm_apic_set_version (struct kvm_vcpu * vcpu )
147
+ {
148
+ struct kvm_lapic * apic = vcpu -> arch .apic ;
149
+ struct kvm_cpuid_entry2 * feat ;
150
+ u32 v = APIC_VERSION ;
151
+
152
+ if (!irqchip_in_kernel (vcpu -> kvm ))
153
+ return ;
154
+
155
+ feat = kvm_find_cpuid_entry (apic -> vcpu , 0x1 , 0 );
156
+ if (feat && (feat -> ecx & (1 << (X86_FEATURE_X2APIC & 31 ))))
157
+ v |= APIC_LVR_DIRECTED_EOI ;
158
+ apic_set_reg (apic , APIC_LVR , v );
159
+ }
160
+
145
161
static unsigned int apic_lvt_mask [APIC_LVT_NUM ] = {
146
162
LVT_MASK | APIC_LVT_TIMER_PERIODIC , /* LVTT */
147
163
LVT_MASK | APIC_MODE_MASK , /* LVTTHMR */
@@ -442,9 +458,11 @@ static void apic_set_eoi(struct kvm_lapic *apic)
442
458
trigger_mode = IOAPIC_LEVEL_TRIG ;
443
459
else
444
460
trigger_mode = IOAPIC_EDGE_TRIG ;
445
- mutex_lock (& apic -> vcpu -> kvm -> irq_lock );
446
- kvm_ioapic_update_eoi (apic -> vcpu -> kvm , vector , trigger_mode );
447
- mutex_unlock (& apic -> vcpu -> kvm -> irq_lock );
461
+ if (!(apic_get_reg (apic , APIC_SPIV ) & APIC_SPIV_DIRECTED_EOI )) {
462
+ mutex_lock (& apic -> vcpu -> kvm -> irq_lock );
463
+ kvm_ioapic_update_eoi (apic -> vcpu -> kvm , vector , trigger_mode );
464
+ mutex_unlock (& apic -> vcpu -> kvm -> irq_lock );
465
+ }
448
466
}
449
467
450
468
static void apic_send_ipi (struct kvm_lapic * apic )
@@ -694,8 +712,11 @@ static int apic_mmio_write(struct kvm_io_device *this,
694
712
apic_set_reg (apic , APIC_DFR , val | 0x0FFFFFFF );
695
713
break ;
696
714
697
- case APIC_SPIV :
698
- apic_set_reg (apic , APIC_SPIV , val & 0x3ff );
715
+ case APIC_SPIV : {
716
+ u32 mask = 0x3ff ;
717
+ if (apic_get_reg (apic , APIC_LVR ) & APIC_LVR_DIRECTED_EOI )
718
+ mask |= APIC_SPIV_DIRECTED_EOI ;
719
+ apic_set_reg (apic , APIC_SPIV , val & mask );
699
720
if (!(val & APIC_SPIV_APIC_ENABLED )) {
700
721
int i ;
701
722
u32 lvt_val ;
@@ -710,7 +731,7 @@ static int apic_mmio_write(struct kvm_io_device *this,
710
731
711
732
}
712
733
break ;
713
-
734
+ }
714
735
case APIC_ICR :
715
736
/* No delay here, so we always clear the pending bit */
716
737
apic_set_reg (apic , APIC_ICR , val & ~(1 << 12 ));
@@ -837,7 +858,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
837
858
hrtimer_cancel (& apic -> lapic_timer .timer );
838
859
839
860
apic_set_reg (apic , APIC_ID , vcpu -> vcpu_id << 24 );
840
- apic_set_reg (apic , APIC_LVR , APIC_VERSION );
861
+ kvm_apic_set_version (apic -> vcpu );
841
862
842
863
for (i = 0 ; i < APIC_LVT_NUM ; i ++ )
843
864
apic_set_reg (apic , APIC_LVTT + 0x10 * i , APIC_LVT_MASKED );
@@ -1041,7 +1062,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
1041
1062
1042
1063
apic -> base_address = vcpu -> arch .apic_base &
1043
1064
MSR_IA32_APICBASE_BASE ;
1044
- apic_set_reg (apic , APIC_LVR , APIC_VERSION );
1065
+ kvm_apic_set_version (vcpu );
1066
+
1045
1067
apic_update_ppr (apic );
1046
1068
hrtimer_cancel (& apic -> lapic_timer .timer );
1047
1069
update_divide_count (apic );
0 commit comments