[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v8 02/21] xen/vlapic: fixes for HVM code when running without a vlapic
The HVM related code (SVM, VMX) generally assumed that a local apic is always present. With the introduction of a HVM mode were the local apic can be removed, some of this broken code paths arised. The SVM exit/resume paths unconditionally checked the state of the lapic, which is wrong if it's been disabled by hardware, fix this by adding the necessary checks. On the VMX side, make sure we don't add mappings for a local apic if it's disabled. In the generic vlapic code, add checks to prevent setting the TSC deadline timer if the lapic is disabled, and also prevent trying to inject interrupts from the PIC is the lapic is also disabled. Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Cc: Jun Nakajima <jun.nakajima@xxxxxxxxx> Cc: Eddie Dong <eddie.dong@xxxxxxxxx> Cc: Kevin Tian <kevin.tian@xxxxxxxxx> --- Changes since v7: - Only check apic_access_mfn in vmx_install_vlapic_mapping, and add an assert. - Return 0 (instead of -ENODEV) in vlapic_accept_pic_intr if the vlapic is disabled. - Add Boris Ostrovsky Reviewed-by tag. --- xen/arch/x86/hvm/svm/svm.c | 18 ++++++++++-------- xen/arch/x86/hvm/vlapic.c | 7 ++++++- xen/arch/x86/hvm/vmx/vmx.c | 4 +++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 8de41fa..404634b 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1035,6 +1035,7 @@ static void noreturn svm_do_resume(struct vcpu *v) struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; bool_t debug_state = v->domain->debugger_attached; bool_t vcpu_guestmode = 0; + struct vlapic *vlapic = vcpu_vlapic(v); if ( nestedhvm_enabled(v->domain) && nestedhvm_vcpu_in_guestmode(v) ) vcpu_guestmode = 1; @@ -1058,14 +1059,14 @@ static void noreturn svm_do_resume(struct vcpu *v) hvm_asid_flush_vcpu(v); } - if ( !vcpu_guestmode ) + if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic) ) { vintr_t intr; /* Reflect the vlapic's TPR in the hardware vtpr */ intr = vmcb_get_vintr(vmcb); intr.fields.tpr = - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4; + (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4; vmcb_set_vintr(vmcb, intr); } @@ -2294,6 +2295,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) int inst_len, rc; vintr_t intr; bool_t vcpu_guestmode = 0; + struct vlapic *vlapic = vcpu_vlapic(v); hvm_invalidate_regs_fields(regs); @@ -2311,11 +2313,12 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) * NB. We need to preserve the low bits of the TPR to make checked builds * of Windows work, even though they don't actually do anything. */ - if ( !vcpu_guestmode ) { + if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic) ) + { intr = vmcb_get_vintr(vmcb); - vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI, + vlapic_set_reg(vlapic, APIC_TASKPRI, ((intr.fields.tpr & 0x0F) << 4) | - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0x0F)); + (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0x0F)); } exit_reason = vmcb->exitcode; @@ -2697,14 +2700,13 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) } out: - if ( vcpu_guestmode ) - /* Don't clobber TPR of the nested guest. */ + if ( vcpu_guestmode || vlapic_hw_disabled(vlapic) ) return; /* The exit may have updated the TPR: reflect this in the hardware vtpr */ intr = vmcb_get_vintr(vmcb); intr.fields.tpr = - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4; + (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4; vmcb_set_vintr(vmcb, intr); } diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index b893b40..0debe5e 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -1042,7 +1042,9 @@ void vlapic_tdt_msr_set(struct vlapic *vlapic, uint64_t value) uint64_t guest_tsc; struct vcpu *v = vlapic_vcpu(vlapic); - /* may need to exclude some other conditions like vlapic->hw.disabled */ + if ( vlapic_hw_disabled(vlapic) ) + return; + if ( !vlapic_lvtt_tdt(vlapic) ) { HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "ignore tsc deadline msr write"); @@ -1118,6 +1120,9 @@ static int __vlapic_accept_pic_intr(struct vcpu *v) int vlapic_accept_pic_intr(struct vcpu *v) { + if ( vlapic_hw_disabled(vcpu_vlapic(v)) ) + return 0; + TRACE_2D(TRC_HVM_EMUL_LAPIC_PIC_INTR, (v == v->domain->arch.hvm_domain.i8259_target), v ? __vlapic_accept_pic_intr(v) : -1); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index bbec0e8..fcfd70b 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2412,9 +2412,11 @@ static void vmx_install_vlapic_mapping(struct vcpu *v) { paddr_t virt_page_ma, apic_page_ma; - if ( !cpu_has_vmx_virtualize_apic_accesses ) + if ( v->domain->arch.hvm_domain.vmx.apic_access_mfn == 0 ) return; + ASSERT(cpu_has_vmx_virtualize_apic_accesses); + virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page); apic_page_ma = v->domain->arch.hvm_domain.vmx.apic_access_mfn; apic_page_ma <<= PAGE_SHIFT; -- 1.9.5 (Apple Git-50.3) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |