Add APIC register virtualization support - APIC read doesn't cause VM-Exit - APIC write becomes trap-like Signed-off-by: Yang Zhang <yang.z.zhang@intel.com> Signed-off-by: Jiongxi Li <jiongxi.li@intel.com> diff -r 1126b3079bef xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/arch/x86/hvm/vlapic.c Thu Aug 30 22:38:26 2012 +0800 @@ -823,6 +823,16 @@ static int vlapic_write(struct vcpu *v, return rc; } +int vlapic_apicv_write(struct vcpu *v, unsigned int offset) +{ + uint32_t val = vlapic_get_reg(vcpu_vlapic(v), offset); + + ASSERT(cpu_has_vmx_apic_reg_virt); + + vlapic_reg_write(v, offset, val); + return 0; +} + int hvm_x2apic_msr_write(struct vcpu *v, unsigned int msr, uint64_t msr_content) { struct vlapic *vlapic = vcpu_vlapic(v); diff -r 1126b3079bef xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Thu Aug 30 22:38:26 2012 +0800 @@ -89,6 +89,7 @@ static void __init vmx_display_features( P(cpu_has_vmx_vnmi, "Virtual NMI"); P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap"); P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest"); + P(cpu_has_vmx_apic_reg_virt, "APIC Register Virtualization"); #undef P if ( !printed ) @@ -186,6 +187,14 @@ static int vmx_init_vmcs_config(void) if ( opt_unrestricted_guest_enabled ) opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST; + /* + * "APIC Register Virtualization" + * can be set only when "use TPR shadow" is set + */ + if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW ) + opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT; + + _vmx_secondary_exec_control = adjust_vmx_controls( "Secondary Exec Control", min, opt, MSR_IA32_VMX_PROCBASED_CTLS2, &mismatch); diff -r 1126b3079bef xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Aug 30 22:38:26 2012 +0800 @@ -2273,6 +2273,14 @@ static void vmx_idtv_reinject(unsigned l } } +static int vmx_handle_apic_write(void) +{ + unsigned long exit_qualification = __vmread(EXIT_QUALIFICATION); + unsigned int offset = exit_qualification & 0xfff; + + return vlapic_apicv_write(current, offset); +} + void vmx_vmexit_handler(struct cpu_user_regs *regs) { unsigned int exit_reason, idtv_info, intr_info = 0, vector = 0; @@ -2728,6 +2736,11 @@ void vmx_vmexit_handler(struct cpu_user_ break; } + case EXIT_REASON_APIC_WRITE: + if ( vmx_handle_apic_write() ) + hvm_inject_hw_exception(TRAP_gp_fault, 0); + break; + case EXIT_REASON_ACCESS_GDTR_OR_IDTR: case EXIT_REASON_ACCESS_LDTR_OR_TR: case EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED: diff -r 1126b3079bef xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/include/asm-x86/hvm/vlapic.h Thu Aug 30 22:38:26 2012 +0800 @@ -103,6 +103,8 @@ void vlapic_EOI_set(struct vlapic *vlapi int vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high); +int vlapic_apicv_write(struct vcpu *v, unsigned int offset); + struct vlapic *vlapic_lowest_prio( struct domain *d, struct vlapic *source, int short_hand, uint8_t dest, uint8_t dest_mode); diff -r 1126b3079bef xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Aug 30 22:38:26 2012 +0800 @@ -182,6 +182,7 @@ extern u32 vmx_vmentry_control; #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 extern u32 vmx_secondary_exec_control; @@ -230,6 +231,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr SECONDARY_EXEC_UNRESTRICTED_GUEST) #define cpu_has_vmx_ple \ (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) +#define cpu_has_vmx_apic_reg_virt \ + (vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT) /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001 diff -r 1126b3079bef xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri Aug 24 12:38:18 2012 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Aug 30 22:38:26 2012 +0800 @@ -129,6 +129,7 @@ void vmx_update_cpu_exec_control(struct #define EXIT_REASON_INVVPID 53 #define EXIT_REASON_WBINVD 54 #define EXIT_REASON_XSETBV 55 +#define EXIT_REASON_APIC_WRITE 56 #define EXIT_REASON_INVPCID 58 /* _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Jan Beulich
2012-Aug-31 12:14 UTC
Re: [ PATCH 1/2] xen: enable APIC-Register Virtualization
>>> On 31.08.12 at 11:29, "Li, Jiongxi" <jiongxi.li@intel.com> wrote: > --- a/xen/arch/x86/hvm/vlapic.c Fri Aug 24 12:38:18 2012 +0100 > +++ b/xen/arch/x86/hvm/vlapic.c Thu Aug 30 22:38:26 2012 +0800 > @@ -823,6 +823,16 @@ static int vlapic_write(struct vcpu *v, > return rc; > } > > +int vlapic_apicv_write(struct vcpu *v, unsigned int offset) > +{ > + uint32_t val = vlapic_get_reg(vcpu_vlapic(v), offset); > + > + ASSERT(cpu_has_vmx_apic_reg_virt);Given the function and the assertion are in a common file, both should be named without using VMX specific terms (or moved elsewhere). Jan> + > + vlapic_reg_write(v, offset, val); > + return 0; > +} > +
Zhang, Yang Z
2012-Sep-02 23:47 UTC
Re: [ PATCH 1/2] xen: enable APIC-Register Virtualization
Jan Beulich wrote on 2012-08-31:>>>> On 31.08.12 at 11:29, "Li, Jiongxi" <jiongxi.li@intel.com> wrote: >> --- a/xen/arch/x86/hvm/vlapic.c Fri Aug 24 12:38:18 2012 +0100 >> +++ b/xen/arch/x86/hvm/vlapic.c Thu Aug 30 22:38:26 2012 +0800 >> @@ -823,6 +823,16 @@ static int vlapic_write(struct vcpu *v, >> return rc; >> } >> >> +int vlapic_apicv_write(struct vcpu *v, unsigned int offset) >> +{ >> + uint32_t val = vlapic_get_reg(vcpu_vlapic(v), offset); >> + >> + ASSERT(cpu_has_vmx_apic_reg_virt); > > Given the function and the assertion are in a common file, both should > be named without using VMX specific terms (or moved elsewhere).Correct. Since the common VM exits handlers are in vmx.c, it''s better to put this to vmx.c too. Best regards, Yang> > Jan > >> + >> + vlapic_reg_write(v, offset, val); >> + return 0; >> +} >> + > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel
Li, Jiongxi
2012-Sep-06 10:00 UTC
Re: [ PATCH 1/2] xen: enable APIC-Register Virtualization
Sorry for the late response.> -----Original Message----- > From: Jan Beulich [mailto:JBeulich@suse.com] > Sent: Friday, August 31, 2012 8:15 PM > To: Li, Jiongxi > Cc: xen-devel@lists.xen.org > Subject: Re: [Xen-devel] [ PATCH 1/2] xen: enable APIC-Register Virtualization > > >>> On 31.08.12 at 11:29, "Li, Jiongxi" <jiongxi.li@intel.com> wrote: > > --- a/xen/arch/x86/hvm/vlapic.c Fri Aug 24 12:38:18 2012 +0100 > > +++ b/xen/arch/x86/hvm/vlapic.c Thu Aug 30 22:38:26 2012 +0800 > > @@ -823,6 +823,16 @@ static int vlapic_write(struct vcpu *v, > > return rc; > > } > > > > +int vlapic_apicv_write(struct vcpu *v, unsigned int offset) { > > + uint32_t val = vlapic_get_reg(vcpu_vlapic(v), offset); > > + > > + ASSERT(cpu_has_vmx_apic_reg_virt); > > Given the function and the assertion are in a common file, both should be > named without using VMX specific terms (or moved elsewhere).Ok, will may the change> > Jan > > > + > > + vlapic_reg_write(v, offset, val); > > + return 0; > > +} > > + >