Alex,
On 8/19/2019 5:42 AM, Alexander Graf wrote:
OnÂ15.08.19Â18:25,ÂSuthikulpanit,ÂSuraveeÂwrote:
ACKÂnotifiersÂdon'tÂworkÂwithÂAMDÂSVMÂw/ÂAVICÂwhenÂtheÂPITÂinterrupt
isÂdeliveredÂasÂedge-triggeredÂfixedÂinterruptÂsinceÂAMDÂprocessors
cannotÂexitÂonÂEOIÂforÂtheseÂinterrupts.
AddÂcodeÂtoÂcheckÂLAPICÂpendingÂEOIÂbeforeÂinjectingÂanyÂpendingÂPIT
interruptÂonÂAMDÂSVMÂwhenÂAVICÂisÂactivated.
Signed-off-by:ÂSuraveeÂSuthikulpanit <suravee.suthikulpanit@xxxxxxx>
---
ÂÂarch/x86/kvm/i8254.cÂ|Â31Â+++++++++++++++++++++++++------
ÂÂ1ÂfileÂchanged,Â25Âinsertions(+),Â6Âdeletions(-)
diffÂ--gitÂa/arch/x86/kvm/i8254.cÂb/arch/x86/kvm/i8254.c
indexÂ4a6dc54..31c4a9bÂ100644
---Âa/arch/x86/kvm/i8254.c
+++Âb/arch/x86/kvm/i8254.c
@@Â-34,10Â+34,12Â@@
ÂÂ#includeÂ<linux/kvm_host.h>
ÂÂ#includeÂ<linux/slab.h>
+#includeÂ<asm/virtext.h>
ÂÂ#includeÂ"ioapic.h"
ÂÂ#includeÂ"irq.h"
ÂÂ#includeÂ"i8254.h"
+#includeÂ"lapic.h"
ÂÂ#includeÂ"x86.h"
ÂÂ#ifndefÂCONFIG_X86_64
@@Â-236,6Â+238,12Â@@ÂstaticÂvoidÂdestroy_pit_timer(structÂkvm_pitÂ*pit)
ÂÂÂÂÂÂkthread_flush_work(&pit->expired);
ÂÂ}
+staticÂinlineÂvoidÂkvm_pit_reset_reinject(structÂkvm_pitÂ*pit)
+{
+ÂÂÂÂatomic_set(&pit->pit_state.pending,Â0);
+ÂÂÂÂatomic_set(&pit->pit_state.irq_ack,Â1);
+}
+
ÂÂstaticÂvoidÂpit_do_work(structÂkthread_workÂ*work)
ÂÂ{
ÂÂÂÂÂÂstructÂkvm_pitÂ*pitÂ=Âcontainer_of(work,ÂstructÂkvm_pit,Âexpired);
@@Â-244,6Â+252,23Â@@ÂstaticÂvoidÂpit_do_work(structÂkthread_workÂ*work)
ÂÂÂÂÂÂintÂi;
ÂÂÂÂÂÂstructÂkvm_kpit_stateÂ*psÂ=Â&pit->pit_state;
+ÂÂÂÂ/*
+ÂÂÂÂÂ*ÂSince,ÂAMDÂSVMÂAVICÂacceleratesÂwriteÂaccessÂtoÂAPICÂEOI
+ÂÂÂÂÂ*ÂregisterÂforÂedge-triggerÂinterrupts.ÂPITÂwillÂnotÂbeÂable
+ÂÂÂÂÂ*ÂtoÂreceiveÂtheÂIRQÂACKÂnotifierÂandÂwillÂalwaysÂbeÂzero.
+ÂÂÂÂÂ*ÂTherefore,ÂweÂcheckÂifÂanyÂLAPICÂEOIÂpendingÂforÂvectorÂ0
+ÂÂÂÂÂ*ÂandÂresetÂirq_ackÂifÂnoÂpending.
+ÂÂÂÂÂ*/
+ÂÂÂÂifÂ(cpu_has_svm(NULL)Â&&Âkvm->arch.apicv_stateÂ==ÂAPICV_ACTIVATED)Â{
+ÂÂÂÂÂÂÂÂintÂeoiÂ=Â0;
+
+ÂÂÂÂÂÂÂÂkvm_for_each_vcpu(i,Âvcpu,Âkvm)
+ÂÂÂÂÂÂÂÂÂÂÂÂifÂ(kvm_apic_pending_eoi(vcpu,Â0))
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂeoi++;
+ÂÂÂÂÂÂÂÂifÂ(!eoi)
+ÂÂÂÂÂÂÂÂÂÂÂÂkvm_pit_reset_reinject(pit);
InÂwhichÂcaseÂwouldÂeoiÂbeÂ!=Â0ÂwhenÂAPIC-VÂisÂactive?
That would be the case when guest has not processed and/or still processing the interrupt.
Once the guest writes to APIC EOI register for edge-triggered interrupt for vector 0,
and the AVIC hardware accelerated the access by clearing the highest priority ISR bit,
then the eoi should be zero.