diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 26b1ad59f6..d3e7ac91c7 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2167,6 +2167,7 @@ void vmx_vlapic_msr_changed(struct vcpu *v) { int virtualize_x2apic_mode; struct vlapic *vlapic = vcpu_vlapic(v); + unsigned int msr; virtualize_x2apic_mode = ( (cpu_has_vmx_apic_reg_virt || cpu_has_vmx_virtual_intr_delivery) && @@ -2183,8 +2184,6 @@ void vmx_vlapic_msr_changed(struct vcpu *v) if ( !vlapic_hw_disabled(vlapic) && (vlapic_base_address(vlapic) == APIC_DEFAULT_PHYS_BASE) ) { - unsigned int msr; - if ( virtualize_x2apic_mode && vlapic_x2apic_mode(vlapic) ) { v->arch.hvm_vmx.secondary_exec_control |= @@ -2213,15 +2212,15 @@ void vmx_vlapic_msr_changed(struct vcpu *v) } } else - { v->arch.hvm_vmx.secondary_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; - for ( msr = MSR_IA32_APICBASE_MSR; - msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ ) - vmx_enable_intercept_for_msr(v, msr, - MSR_TYPE_R | MSR_TYPE_W); - } } + if ( !(v->arch.hvm_vmx.secondary_exec_control & + SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE) ) + for ( msr = MSR_IA32_APICBASE_MSR; + msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ ) + vmx_enable_intercept_for_msr(v, msr, MSR_TYPE_R | MSR_TYPE_W); + vmx_update_secondary_exec_control(v); vmx_vmcs_exit(v); } diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 42835d0341..ade555b655 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -442,19 +442,30 @@ UNLIKELY_START(z, create_bounce_frame_bad_bounce_ip) __UNLIKELY_END(create_bounce_frame_bad_bounce_ip) movq %rax,UREGS_rip+8(%rsp) ret - _ASM_EXTABLE(.Lft2, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft3, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft4, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft5, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft6, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft7, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft8, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft9, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft10, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft11, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft12, dom_crash_sync_extable) - _ASM_EXTABLE(.Lft13, dom_crash_sync_extable) + _ASM_EXTABLE(.Lft2, domain_crash_page_fault_32) + _ASM_EXTABLE(.Lft3, domain_crash_page_fault_24) + _ASM_EXTABLE(.Lft4, domain_crash_page_fault_8) + _ASM_EXTABLE(.Lft5, domain_crash_page_fault_16) + _ASM_EXTABLE(.Lft6, domain_crash_page_fault) + _ASM_EXTABLE(.Lft7, domain_crash_page_fault) + _ASM_EXTABLE(.Lft8, domain_crash_page_fault_24) + _ASM_EXTABLE(.Lft9, domain_crash_page_fault_16) + _ASM_EXTABLE(.Lft10, domain_crash_page_fault_8) + _ASM_EXTABLE(.Lft11, domain_crash_page_fault) + _ASM_EXTABLE(.Lft12, domain_crash_page_fault_8) + _ASM_EXTABLE(.Lft13, domain_crash_page_fault) +domain_crash_page_fault_32: + addq $8,%rsi +domain_crash_page_fault_24: + addq $8,%rsi +domain_crash_page_fault_16: + addq $8,%rsi +domain_crash_page_fault_8: + addq $8,%rsi +domain_crash_page_fault: + movq %rsi,%rdi + call show_page_walk ENTRY(dom_crash_sync_extable) # Get out of the guest-save area of the stack. GET_STACK_BASE(%rax) diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c index ef75b94dc4..4cd32b5985 100644 --- a/xen/drivers/passthrough/io.c +++ b/xen/drivers/passthrough/io.c @@ -513,45 +513,39 @@ void hvm_dpci_msi_eoi(struct domain *d, int vector) spin_unlock(&d->event_lock); } -static void hvm_pci_msi_assert( - struct domain *d, struct hvm_pirq_dpci *pirq_dpci) -{ - struct pirq *pirq = dpci_pirq(pirq_dpci); - - if ( hvm_domain_use_pirq(d, pirq) ) - send_guest_pirq(d, pirq); - else - vmsi_deliver_pirq(d, pirq_dpci); -} - static int _hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci, void *arg) { if ( test_and_clear_bool(pirq_dpci->masked) ) { + struct pirq *pirq = dpci_pirq(pirq_dpci); const struct dev_intx_gsi_link *digl; + if ( hvm_domain_use_pirq(d, pirq) ) + { + send_guest_pirq(d, pirq); + + if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI ) + return 0; + } + if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI ) { - hvm_pci_msi_assert(d, pirq_dpci); + vmsi_deliver_pirq(d, pirq_dpci); return 0; } list_for_each_entry ( digl, &pirq_dpci->digl_list, list ) { - struct pirq *info = dpci_pirq(pirq_dpci); - - if ( hvm_domain_use_pirq(d, info) ) - send_guest_pirq(d, info); - else - hvm_pci_intx_assert(d, digl->device, digl->intx); + hvm_pci_intx_assert(d, digl->device, digl->intx); pirq_dpci->pending++; + } - if ( pirq_dpci->flags & HVM_IRQ_DPCI_TRANSLATE ) - { - /* for translated MSI to INTx interrupt, eoi as early as possible */ - __msi_pirq_eoi(pirq_dpci); - } + if ( pirq_dpci->flags & HVM_IRQ_DPCI_TRANSLATE ) + { + /* for translated MSI to INTx interrupt, eoi as early as possible */ + __msi_pirq_eoi(pirq_dpci); + return 0; } /* @@ -561,8 +555,8 @@ static int _hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci, * guest will never deal with the irq, then the physical interrupt line * will never be deasserted. */ - if ( pt_irq_need_timer(pirq_dpci->flags) ) - set_timer(&pirq_dpci->timer, NOW() + PT_IRQ_TIME_OUT); + ASSERT(pt_irq_need_timer(pirq_dpci->flags)); + set_timer(&pirq_dpci->timer, NOW() + PT_IRQ_TIME_OUT); } return 0; @@ -583,12 +577,12 @@ static void __hvm_dpci_eoi(struct domain *d, const struct hvm_girq_dpci_mapping *girq, const union vioapic_redir_entry *ent) { - struct pirq *pirq; + struct pirq *pirq = pirq_info(d, girq->machine_gsi); struct hvm_pirq_dpci *pirq_dpci; - hvm_pci_intx_deassert(d, girq->device, girq->intx); + if ( !hvm_domain_use_pirq(d, pirq) ) + hvm_pci_intx_deassert(d, girq->device, girq->intx); - pirq = pirq_info(d, girq->machine_gsi); pirq_dpci = pirq_dpci(pirq); /*