On Thu, Nov 22, 2007 at 05:00:41AM +0100, tgingold@xxxxxxx wrote:
> diff -r 092232fa1fbd xen/arch/ia64/vmx/vmx_fault.c
...snip...
> @@ -248,59 +256,62 @@ void leave_hypervisor_tail(void)
> struct domain *d = current->domain;
> struct vcpu *v = current;
>
> + /* FIXME: can this happen ? */
> + if (is_idle_domain(current->domain))
> + return;
> +
> + if (d->arch.is_hvmstub) {
> + if (local_events_need_delivery()) {
> + hvmstub_deliver_event ();
> + }
> + } else if (v->vcpu_id == 0) {
> + unsigned long callback_irq =
> + d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
> +
> + if ( v->arch.arch_vmx.pal_init_pending ) {
> + /*inject INIT interruption to guest pal*/
> + v->arch.arch_vmx.pal_init_pending = 0;
> + deliver_pal_init(v);
> + return;
> + }
> +
> + /*
> + * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
> + * Domain = val[47:32], Bus = val[31:16],
> + * DevFn = val[15: 8], IntX = val[ 1: 0]
> + * val[63:56] == 0: val[55:0] is a delivery as GSI
> + */
> + if (callback_irq != 0 && local_events_need_delivery()) {
> + /* change level for para-device callback irq */
> + /* use level irq to send discrete event */
> + if ((uint8_t)(callback_irq >> 56) == 1) {
> + /* case of using PCI INTx line as callback irq */
> + int pdev = (callback_irq >> 11) & 0x1f;
> + int pintx = callback_irq & 3;
> + viosapic_set_pci_irq(d, pdev, pintx, 1);
> + viosapic_set_pci_irq(d, pdev, pintx, 0);
> + } else {
> + /* case of using GSI as callback irq */
> + viosapic_set_irq(d, callback_irq, 1);
> + viosapic_set_irq(d, callback_irq, 0);
> + }
> + }
> + }
> +
> + rmb();
> + if (xchg(&v->arch.irq_new_pending, 0)) {
> + v->arch.irq_new_condition = 0;
> + vmx_check_pending_irq(v);
> + }
> + else if (v->arch.irq_new_condition) {
> + v->arch.irq_new_condition = 0;
> + vhpi_detection(v);
> + }
> +
> // FIXME: Will this work properly if doing an RFI???
> - if (!is_idle_domain(d) ) { // always comes from guest
> -// struct pt_regs *user_regs = vcpu_regs(current);
> - local_irq_enable();
> - do_softirq();
> - local_irq_disable();
> -
> - if (v->vcpu_id == 0) {
> - unsigned long callback_irq =
> - d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
> -
> - if ( v->arch.arch_vmx.pal_init_pending ) {
> - /*inject INIT interruption to guest pal*/
> - v->arch.arch_vmx.pal_init_pending = 0;
> - deliver_pal_init(v);
> - return;
> - }
> -
> - /*
> - * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
> - * Domain = val[47:32], Bus = val[31:16],
> - * DevFn = val[15: 8], IntX = val[ 1: 0]
> - * val[63:56] == 0: val[55:0] is a delivery as GSI
> - */
> - if (callback_irq != 0 && local_events_need_delivery()) {
> - /* change level for para-device callback irq */
> - /* use level irq to send discrete event */
> - if ((uint8_t)(callback_irq >> 56) == 1) {
> - /* case of using PCI INTx line as callback irq */
> - int pdev = (callback_irq >> 11) & 0x1f;
> - int pintx = callback_irq & 3;
> - viosapic_set_pci_irq(d, pdev, pintx, 1);
> - viosapic_set_pci_irq(d, pdev, pintx, 0);
> - } else {
> - /* case of using GSI as callback irq */
> - viosapic_set_irq(d, callback_irq, 1);
> - viosapic_set_irq(d, callback_irq, 0);
> - }
> - }
> - }
> -
> - rmb();
> - if (xchg(&v->arch.irq_new_pending, 0)) {
> - v->arch.irq_new_condition = 0;
> - vmx_check_pending_irq(v);
> - return;
> - }
> -
> - if (v->arch.irq_new_condition) {
> - v->arch.irq_new_condition = 0;
> - vhpi_detection(v);
> - }
> - }
> + local_irq_enable();
> + do_softirq();
> + local_irq_disable();
> }
>
> static int vmx_handle_lds(REGS* regs)
do_softirq() should be called before the device emulation code.
The device emulation code uses timer and the timer callbacks which
are called by softirq may change the device status and trigger interrupts.
--
yamahata
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|