kvm/x86: implement hv EOI assist
PATCH 1/1 kvm/x86: implement hv EOI assist
It seems that it's easy to implement the EOI assist on top of the PV EOI feature: simply convert the page address to the format expected by PV EOI.
Notes:
-"No EOI required" is set only if interrupt injected
is edge triggered; this is true because level interrupts are going through IOAPIC which disables PV EOI.
In any case, if guest triggers EOI the bit will get cleared on exit.
-For migration, set of HV_X64_MSR_APIC_ASSIST_PAGE sets
KVM_PV_EOI_EN internally, so restoring HV_X64_MSR_APIC_ASSIST_PAGE seems sufficient
In any case, bit is cleared on exit so worst case it's never re-enabled
-no handling of PV EOI data is performed at HV_X64_MSR_EOI write;
HV_X64_MSR_EOI is a separate optimization - it's an X2APIC replacement that lets you do EOI with an MSR and not IO.
---
patch is unchanged from RFC except for documenting the design points in the commit log, do address Marcelo's comments.
This passed basic testing. Migration was not tested.
I think at this point it's a good idea to merge this so it can get tested and used by more people.
arch/x86/kvm/x86.c +4 -0
@@ -1890,6 +1890,8 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)if (!(data &HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE )) { vcpu->arch.hv_vapic = data; +if (kvm_lapic_enable_pv_eoi (vcpu,0 )) +return 1 ;break ; } gfn = data >>HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT ;
@@ -1900,6 +1902,8 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)return 1 ; vcpu->arch.hv_vapic = data;mark_page_dirty (vcpu->kvm, gfn); +if (kvm_lapic_enable_pv_eoi (vcpu,gfn_to_gpa (gfn) |KVM_MSR_ENABLED )) +return 1 ;break ; }case HV_X64_MSR_EOI :
Paolo Bonzini
maintainerIl 07/05/2014 15:29, Michael S. Tsirkin ha scritto:
Quoted 43 lines
It seems that it's easy to implement the EOI assist on top of the PV EOI feature: simply convert the page address to the format expected by PV EOI.
Notes:
-"No EOI required" is set only if interrupt injected
is edge triggered; this is true because level interrupts are going through IOAPIC which disables PV EOI.
In any case, if guest triggers EOI the bit will get cleared on exit.(quoted diff) +0
-2-For migration, set of HV_X64_MSR_APIC_ASSIST_PAGE sets KVM_PV_EOI_EN internally, so restoring HV_X64_MSR_APIC_ASSIST_PAGE seems sufficient In any case, bit is cleared on exit so worst case it's never re-enabled -no handling of PV EOI data is performed at HV_X64_MSR_EOI write; HV_X64_MSR_EOI is a separate optimization - it's an X2APIC replacement that lets you do EOI with an MSR and not IO.Signed-off-by Michael S. Tsirkin <[email protected]>---
patch is unchanged from RFC except for documenting the design points in the commit log, do address Marcelo's comments.
This passed basic testing. Migration was not tested.I think at this point it's a good idea to merge this so it can get tested and used by more people.
arch/x86/kvm/x86.c +2
-0@@ -1890,6 +1890,8 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)if (!(data &HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE )) { vcpu->arch.hv_vapic = data; +if (kvm_lapic_enable_pv_eoi (vcpu,0 )) +return 1 ;break ; } gfn = data >>HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT ;
arch/x86/kvm/x86.c static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data) · line 1909
Quoted 8 lines
arch/x86/kvm/x86.c +2
-0@@ -1900,6 +1902,8 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)return 1 ; vcpu->arch.hv_vapic = data;mark_page_dirty (vcpu->kvm, gfn); +if (kvm_lapic_enable_pv_eoi (vcpu,gfn_to_gpa (gfn) |KVM_MSR_ENABLED )) +return 1 ;break ; }case HV_X64_MSR_EOI :
Applying to kvm/queue, thanks.
Paolo