On Thu, Jan 10, 2013 at 03:26:06PM +0800, Yang Zhang wrote: > - APIC read doesn't cause VM-Exit > - APIC write becomes trap-like > > Signed-off-by: Kevin Tian <kevin.tian@xxxxxxxxx> > Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx> > --- > arch/x86/include/asm/vmx.h | 2 ++ > arch/x86/kvm/lapic.c | 15 +++++++++++++++ > arch/x86/kvm/lapic.h | 2 ++ > arch/x86/kvm/vmx.c | 33 ++++++++++++++++++++++++++++++++- > 4 files changed, 51 insertions(+), 1 deletions(-) > > diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h > index e385df9..44c3f7e 100644 > --- a/arch/x86/include/asm/vmx.h > +++ b/arch/x86/include/asm/vmx.h > @@ -66,6 +66,7 @@ > #define EXIT_REASON_EPT_MISCONFIG 49 > #define EXIT_REASON_WBINVD 54 > #define EXIT_REASON_XSETBV 55 > +#define EXIT_REASON_APIC_WRITE 56 > #define EXIT_REASON_INVPCID 58 > > #define VMX_EXIT_REASONS \ > @@ -141,6 +142,7 @@ > #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 > #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 > #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 > +#define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100 > #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 > #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 > > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c > index 9392f52..0664c13 100644 > --- a/arch/x86/kvm/lapic.c > +++ b/arch/x86/kvm/lapic.c > @@ -1212,6 +1212,21 @@ void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) > } > EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); > > +/* emulate APIC access in a trap manner */ > +void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) > +{ > + u32 val = 0; > + > + /* hw has done the conditional check and inst decode */ > + offset &= 0xff0; > + > + apic_reg_read(vcpu->arch.apic, offset, 4, &val); > + > + /* TODO: optimize to just emulate side effect w/o one more write */ > + apic_reg_write(vcpu->arch.apic, offset, val); > +} > +EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode); > + > void kvm_free_lapic(struct kvm_vcpu *vcpu) > { > struct kvm_lapic *apic = vcpu->arch.apic; > diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h > index e5ebf9f..9a8ee22 100644 > --- a/arch/x86/kvm/lapic.h > +++ b/arch/x86/kvm/lapic.h > @@ -64,6 +64,8 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); > u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); > void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data); > > +void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset); > + > void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); > void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); > void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 55dfc37..688f43f 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -84,6 +84,9 @@ module_param(vmm_exclusive, bool, S_IRUGO); > static bool __read_mostly fasteoi = 1; > module_param(fasteoi, bool, S_IRUGO); > > +static bool __read_mostly enable_apicv_reg_vid = 1; > +module_param(enable_apicv_reg_vid, bool, S_IRUGO); > + > /* > * If nested=1, nested virtualization is supported, i.e., guests may use > * VMX and be a hypervisor for its own guests. If nested=0, guests may not > @@ -764,6 +767,12 @@ static inline bool cpu_has_vmx_virtualize_apic_accesses(void) > SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; > } > > +static inline bool cpu_has_vmx_apic_register_virt(void) > +{ > + return vmcs_config.cpu_based_2nd_exec_ctrl & > + SECONDARY_EXEC_APIC_REGISTER_VIRT; > +} > + > static inline bool cpu_has_vmx_flexpriority(void) > { > return cpu_has_vmx_tpr_shadow() && > @@ -2541,7 +2550,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) > SECONDARY_EXEC_UNRESTRICTED_GUEST | > SECONDARY_EXEC_PAUSE_LOOP_EXITING | > SECONDARY_EXEC_RDTSCP | > - SECONDARY_EXEC_ENABLE_INVPCID; > + SECONDARY_EXEC_ENABLE_INVPCID | > + SECONDARY_EXEC_APIC_REGISTER_VIRT; > if (adjust_vmx_controls(min2, opt2, > MSR_IA32_VMX_PROCBASED_CTLS2, > &_cpu_based_2nd_exec_control) < 0) > @@ -2552,6 +2562,11 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) > SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) > _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; > #endif > + > + if (!(_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)) > + _cpu_based_2nd_exec_control &= ~( > + SECONDARY_EXEC_APIC_REGISTER_VIRT); No need for () around SECONDARY_EXEC_APIC_REGISTER_VIRT. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html