direct-io.hg

changeset 12275:9a6fb3e2f12d

[HVM] Replace shared-memory PIC state with a set-irq-level hypercall.
This simplifies the IRQ logic significantly and avoids the bogus
hvm_pic_assist() on domain resume path.

There is more work to be done here. At least:
1. set-irq-level should really be set-interrupt-wire-level. Wire
state needs to be distinguished from PIC (in particular, PIC IRR)
state.
2. Hypercalls can be batched in qemu and pushed down in one
multicall.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Nov 07 13:13:52 2006 +0000 (2006-11-07)
parents 6f551093f068
children 9fbb26d47b83
files tools/ioemu/target-i386-dm/i8259-dm.c tools/libxc/xc_misc.c tools/libxc/xenctrl.h xen/arch/ia64/vmx/vlsapic.c xen/arch/ia64/vmx/vmx_init.c xen/arch/ia64/vmx/vmx_process.c xen/arch/ia64/vmx/vmx_support.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vmx/io.c xen/include/asm-ia64/vlsapic.h xen/include/asm-ia64/vmx.h xen/include/asm-ia64/vmx_vpd.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/vioapic.h xen/include/asm-x86/hvm/vpic.h xen/include/public/hvm/hvm_op.h xen/include/public/hvm/ioreq.h xen/include/public/hvm/params.h
line diff
     1.1 --- a/tools/ioemu/target-i386-dm/i8259-dm.c	Tue Nov 07 12:31:17 2006 +0000
     1.2 +++ b/tools/ioemu/target-i386-dm/i8259-dm.c	Tue Nov 07 13:13:52 2006 +0000
     1.3 @@ -22,58 +22,18 @@
     1.4   * THE SOFTWARE.
     1.5   */
     1.6  #include "vl.h"
     1.7 -
     1.8 -/* debug PIC */
     1.9 -//#define DEBUG_PIC
    1.10 -
    1.11 -//#define DEBUG_IRQ_LATENCY
    1.12 -//#define DEBUG_IRQ_COUNT
    1.13 -
    1.14  #include "xenctrl.h"
    1.15  #include <xen/hvm/ioreq.h>
    1.16  #include <stdio.h>
    1.17  #include "cpu.h"
    1.18  #include "cpu-all.h"
    1.19  
    1.20 -extern shared_iopage_t *shared_page;
    1.21 -
    1.22  struct PicState2 {
    1.23  };
    1.24  
    1.25  void pic_set_irq_new(void *opaque, int irq, int level)
    1.26  {
    1.27 -    /* PicState2 *s = opaque; */
    1.28 -    global_iodata_t  *gio;
    1.29 -    int  mask;
    1.30 -
    1.31 -    gio = &shared_page->sp_global;
    1.32 -    mask = 1 << irq;
    1.33 -    if ( gio->pic_elcr & mask ) {
    1.34 -        /* level */
    1.35 -       if ( level ) {
    1.36 -           atomic_clear_bit(irq, &gio->pic_clear_irr);
    1.37 -           atomic_set_bit(irq, &gio->pic_irr);
    1.38 -           cpu_single_env->send_event = 1;
    1.39 -       }
    1.40 -       else {
    1.41 -           atomic_clear_bit(irq, &gio->pic_irr);
    1.42 -           atomic_set_bit(irq, &gio->pic_clear_irr);
    1.43 -           cpu_single_env->send_event = 1;
    1.44 -       }
    1.45 -    }
    1.46 -    else {
    1.47 -       /* edge */
    1.48 -       if ( level ) {
    1.49 -           if ( (mask & gio->pic_last_irr) == 0 ) { 
    1.50 -               atomic_set_bit(irq, &gio->pic_irr);
    1.51 -               atomic_set_bit(irq, &gio->pic_last_irr);
    1.52 -               cpu_single_env->send_event = 1;
    1.53 -           }
    1.54 -       }
    1.55 -       else {
    1.56 -           atomic_clear_bit(irq, &gio->pic_last_irr);
    1.57 -       }
    1.58 -    }
    1.59 +    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
    1.60  }
    1.61  
    1.62  /* obsolete function */
     2.1 --- a/tools/libxc/xc_misc.c	Tue Nov 07 12:31:17 2006 +0000
     2.2 +++ b/tools/libxc/xc_misc.c	Tue Nov 07 13:13:52 2006 +0000
     2.3 @@ -5,6 +5,7 @@
     2.4   */
     2.5  
     2.6  #include "xc_private.h"
     2.7 +#include <xen/hvm/hvm_op.h>
     2.8  
     2.9  int xc_readconsolering(int xc_handle,
    2.10                         char **pbuffer,
    2.11 @@ -89,6 +90,33 @@ int xc_perfc_control(int xc_handle,
    2.12      return rc;
    2.13  }
    2.14  
    2.15 +int xc_hvm_set_irq_level(int xc_handle, domid_t dom, int irq, int level)
    2.16 +{
    2.17 +    DECLARE_HYPERCALL;
    2.18 +    struct xen_hvm_set_irq_level arg;
    2.19 +    int rc;
    2.20 +
    2.21 +    hypercall.op     = __HYPERVISOR_hvm_op;
    2.22 +    hypercall.arg[0] = HVMOP_set_irq_level;
    2.23 +    hypercall.arg[1] = (unsigned long)&arg;
    2.24 +
    2.25 +    arg.domid = dom;
    2.26 +    arg.irq   = irq;
    2.27 +    arg.level = level;
    2.28 +
    2.29 +    if ( mlock(&arg, sizeof(arg)) != 0 )
    2.30 +    {
    2.31 +        PERROR("Could not lock memory");
    2.32 +        return -1;
    2.33 +    }
    2.34 +
    2.35 +    rc = do_xen_hypercall(xc_handle, &hypercall);
    2.36 +
    2.37 +    safe_munlock(&arg, sizeof(arg));
    2.38 +
    2.39 +    return rc;
    2.40 +}
    2.41 +
    2.42  /*
    2.43   * Local variables:
    2.44   * mode: C
     3.1 --- a/tools/libxc/xenctrl.h	Tue Nov 07 12:31:17 2006 +0000
     3.2 +++ b/tools/libxc/xenctrl.h	Tue Nov 07 13:13:52 2006 +0000
     3.3 @@ -666,4 +666,6 @@ evtchn_port_t xc_evtchn_pending(int xce_
     3.4   */
     3.5  int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
     3.6  
     3.7 +int xc_hvm_set_irq_level(int xce_handle, domid_t dom, int irq, int level);
     3.8 +
     3.9  #endif
     4.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Tue Nov 07 12:31:17 2006 +0000
     4.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Tue Nov 07 13:13:52 2006 +0000
     4.3 @@ -324,39 +324,6 @@ void vtm_domain_in(VCPU *vcpu)
     4.4   */
     4.5  
     4.6  #ifdef V_IOSAPIC_READY
     4.7 -/* Assist to check virtual interrupt lines */
     4.8 -void vmx_virq_line_assist(struct vcpu *v)
     4.9 -{
    4.10 -    global_iodata_t *spg = &get_sp(v->domain)->sp_global;
    4.11 -    uint16_t *virq_line, irqs;
    4.12 -
    4.13 -    virq_line = &spg->pic_irr;
    4.14 -    if (*virq_line) {
    4.15 -	do {
    4.16 -	    irqs = *(volatile uint16_t*)virq_line;
    4.17 -	} while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
    4.18 -	hvm_vioapic_do_irqs(v->domain, irqs);
    4.19 -    }
    4.20 -
    4.21 -    virq_line = &spg->pic_clear_irr;
    4.22 -    if (*virq_line) {
    4.23 -	do {
    4.24 -	    irqs = *(volatile uint16_t*)virq_line;
    4.25 -	} while ((uint16_t)cmpxchg(virq_line, irqs, 0) != irqs);
    4.26 -	hvm_vioapic_do_irqs_clear(v->domain, irqs);
    4.27 -    }
    4.28 -}
    4.29 -
    4.30 -void vmx_virq_line_init(struct domain *d)
    4.31 -{
    4.32 -    global_iodata_t *spg = &get_sp(d)->sp_global;
    4.33 -
    4.34 -    spg->pic_elcr = 0xdef8; /* Level/Edge trigger mode */
    4.35 -    spg->pic_irr = 0;
    4.36 -    spg->pic_last_irr = 0;
    4.37 -    spg->pic_clear_irr = 0;
    4.38 -}
    4.39 -
    4.40  int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint16_t dest)
    4.41  {
    4.42      return (VLAPIC_ID(s->lapic_info[number]) == dest);
     5.1 --- a/xen/arch/ia64/vmx/vmx_init.c	Tue Nov 07 12:31:17 2006 +0000
     5.2 +++ b/xen/arch/ia64/vmx/vmx_init.c	Tue Nov 07 13:13:52 2006 +0000
     5.3 @@ -322,8 +322,6 @@ vmx_final_setup_guest(struct vcpu *v)
     5.4  	vlsapic_reset(v);
     5.5  	vtm_init(v);
     5.6  
     5.7 -	/* One more step to enable interrupt assist */
     5.8 -	set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags);
     5.9  	/* Set up guest 's indicator for VTi domain*/
    5.10  	set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
    5.11  }
    5.12 @@ -457,9 +455,6 @@ void vmx_setup_platform(struct domain *d
    5.13  	/* initiate spinlock for pass virq */
    5.14  	spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
    5.15  
    5.16 -	/* Initialize the virtual interrupt lines */
    5.17 -	vmx_virq_line_init(d);
    5.18 -
    5.19  	/* Initialize iosapic model within hypervisor */
    5.20  	hvm_vioapic_init(d);
    5.21  }
     6.1 --- a/xen/arch/ia64/vmx/vmx_process.c	Tue Nov 07 12:31:17 2006 +0000
     6.2 +++ b/xen/arch/ia64/vmx/vmx_process.c	Tue Nov 07 13:13:52 2006 +0000
     6.3 @@ -209,10 +209,6 @@ void leave_hypervisor_tail(struct pt_reg
     6.4  //        if (user_regs != regs)
     6.5  //            printk("WARNING: checking pending interrupt in nested interrupt!!!\n");
     6.6  
     6.7 -        /* VMX Domain N has other interrupt source, saying DM  */
     6.8 -        if (test_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags))
     6.9 -                      vmx_intr_assist(v);
    6.10 -
    6.11          /* FIXME: Check event pending indicator, and set
    6.12           * pending bit if necessary to inject back to guest.
    6.13           * Should be careful about window between this check
     7.1 --- a/xen/arch/ia64/vmx/vmx_support.c	Tue Nov 07 12:31:17 2006 +0000
     7.2 +++ b/xen/arch/ia64/vmx/vmx_support.c	Tue Nov 07 13:13:52 2006 +0000
     7.3 @@ -60,27 +60,6 @@ void vmx_io_assist(struct vcpu *v)
     7.4      }
     7.5  }
     7.6  
     7.7 -/*
     7.8 - * VMX domainN has two types of interrupt source: lsapic model within
     7.9 - * HV, and device model within domain 0 (service OS). There're another
    7.10 - * pending array in share page, manipulated by device model directly.
    7.11 - * To conform to VT-i spec, we have to sync pending bits in shared page
    7.12 - * into VPD. This has to be done before checking pending interrupt at
    7.13 - * resume to guest. For domain 0, all the interrupt sources come from
    7.14 - * HV, which then doesn't require this assist.
    7.15 - */
    7.16 -void vmx_intr_assist(struct vcpu *v)
    7.17 -{
    7.18 -#ifdef V_IOSAPIC_READY
    7.19 -    /* Confirm virtual interrupt line signals, and set pending bits in vpd */
    7.20 -    if (spin_trylock(&v->domain->arch.arch_vmx.virq_assist_lock)) {
    7.21 -        vmx_virq_line_assist(v);
    7.22 -        spin_unlock(&v->domain->arch.arch_vmx.virq_assist_lock);
    7.23 -    }
    7.24 -#endif
    7.25 -    return;
    7.26 -}
    7.27 -
    7.28  void vmx_send_assist_req(struct vcpu *v)
    7.29  {
    7.30      ioreq_t *p;
     8.1 --- a/xen/arch/x86/hvm/hvm.c	Tue Nov 07 12:31:17 2006 +0000
     8.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Nov 07 13:13:52 2006 +0000
     8.3 @@ -208,29 +208,6 @@ void pic_irq_request(void *data, int lev
     8.4      *interrupt_request = level;
     8.5  }
     8.6  
     8.7 -void hvm_pic_assist(struct vcpu *v)
     8.8 -{
     8.9 -    global_iodata_t *spg;
    8.10 -    u16   *virq_line, irqs;
    8.11 -    struct hvm_virpic *pic = &v->domain->arch.hvm_domain.vpic;
    8.12 -
    8.13 -    spg = &get_sp(v->domain)->sp_global;
    8.14 -    virq_line  = &spg->pic_clear_irr;
    8.15 -    if ( *virq_line ) {
    8.16 -        do {
    8.17 -            irqs = *(volatile u16*)virq_line;
    8.18 -        } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs );
    8.19 -        do_pic_irqs_clear(pic, irqs);
    8.20 -    }
    8.21 -    virq_line  = &spg->pic_irr;
    8.22 -    if ( *virq_line ) {
    8.23 -        do {
    8.24 -            irqs = *(volatile u16*)virq_line;
    8.25 -        } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs );
    8.26 -        do_pic_irqs(pic, irqs);
    8.27 -    }
    8.28 -}
    8.29 -
    8.30  u64 hvm_get_guest_time(struct vcpu *v)
    8.31  {
    8.32      u64    host_tsc;
    8.33 @@ -679,6 +656,32 @@ long do_hvm_op(unsigned long op, XEN_GUE
    8.34          break;
    8.35      }
    8.36  
    8.37 +    case HVMOP_set_irq_level:
    8.38 +    {
    8.39 +        struct xen_hvm_set_irq_level op;
    8.40 +        struct domain *d;
    8.41 +
    8.42 +        if ( copy_from_guest(&op, arg, 1) )
    8.43 +            return -EFAULT;
    8.44 +
    8.45 +        if ( !IS_PRIV(current->domain) )
    8.46 +            return -EPERM;
    8.47 +
    8.48 +        d = find_domain_by_id(op.domid);
    8.49 +        if ( d == NULL )
    8.50 +            return -ESRCH;
    8.51 +
    8.52 +        rc = -EINVAL;
    8.53 +        if ( is_hvm_domain(d) )
    8.54 +        {
    8.55 +            pic_set_irq(&d->arch.hvm_domain.vpic, op.irq, op.level);
    8.56 +            rc = 0;
    8.57 +        }
    8.58 +
    8.59 +        put_domain(d);
    8.60 +        break;
    8.61 +    }
    8.62 +
    8.63      default:
    8.64      {
    8.65          gdprintk(XENLOG_WARNING, "Bad HVM op %ld.\n", op);
     9.1 --- a/xen/arch/x86/hvm/i8259.c	Tue Nov 07 12:31:17 2006 +0000
     9.2 +++ b/xen/arch/x86/hvm/i8259.c	Tue Nov 07 13:13:52 2006 +0000
     9.3 @@ -152,48 +152,24 @@ void pic_set_xen_irq(void *opaque, int i
     9.4      spin_unlock_irqrestore(&s->lock, flags);
     9.5  }
     9.6  
     9.7 -void pic_set_irq_new(void *opaque, int irq, int level)
     9.8 -{
     9.9 -    struct hvm_virpic *s = opaque;
    9.10 -    unsigned long flags;
    9.11 -
    9.12 -    spin_lock_irqsave(&s->lock, flags);
    9.13 -    hvm_vioapic_set_irq(current->domain, irq, level);
    9.14 -    pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
    9.15 -    pic_update_irq(s);
    9.16 -    spin_unlock_irqrestore(&s->lock, flags);
    9.17 -}
    9.18 -
    9.19 -void do_pic_irqs (struct hvm_virpic *s, uint16_t irqs)
    9.20 +void pic_set_irq(struct hvm_virpic *s, int irq, int level)
    9.21  {
    9.22      unsigned long flags;
    9.23  
    9.24 -    spin_lock_irqsave(&s->lock, flags);
    9.25 -    s->pics[1].irr |= (uint8_t)(irqs >> 8);
    9.26 -    s->pics[0].irr |= (uint8_t) irqs;
    9.27 -    hvm_vioapic_do_irqs(current->domain, irqs);
    9.28 -    pic_update_irq(s);
    9.29 -    spin_unlock_irqrestore(&s->lock, flags);
    9.30 -}
    9.31 -
    9.32 -void do_pic_irqs_clear (struct hvm_virpic *s, uint16_t irqs)
    9.33 -{
    9.34 -    unsigned long flags;
    9.35 +    if ( irq < 0 )
    9.36 +        return;
    9.37  
    9.38      spin_lock_irqsave(&s->lock, flags);
    9.39 -    s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
    9.40 -    s->pics[0].irr &= ~(uint8_t) irqs;
    9.41 -    hvm_vioapic_do_irqs_clear(current->domain, irqs);
    9.42 -    pic_update_irq(s);
    9.43 +    hvm_vioapic_set_irq(container_of(s, struct domain, arch.hvm_domain.vpic),
    9.44 +                        irq, level);
    9.45 +    if ( irq < 16 )
    9.46 +    {
    9.47 +        pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
    9.48 +        pic_update_irq(s);
    9.49 +    }
    9.50      spin_unlock_irqrestore(&s->lock, flags);
    9.51  }
    9.52  
    9.53 -/* obsolete function */
    9.54 -void pic_set_irq(struct hvm_virpic *isa_pic, int irq, int level)
    9.55 -{
    9.56 -    pic_set_irq_new(isa_pic, irq, level);
    9.57 -}
    9.58 -
    9.59  /* acknowledge interrupt 'irq' */
    9.60  static inline void pic_intack(PicState *s, int irq)
    9.61  {
    9.62 @@ -245,26 +221,6 @@ static int pic_read_irq(struct hvm_virpi
    9.63      return intno;
    9.64  }
    9.65  
    9.66 -static void update_shared_irr(struct hvm_virpic *s, PicState *c)
    9.67 -{
    9.68 -    uint8_t *pl, *pe;
    9.69 -
    9.70 -    ASSERT(spin_is_locked(&s->lock));
    9.71 -
    9.72 -    get_sp(current->domain)->sp_global.pic_elcr = 
    9.73 -        s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
    9.74 -    pl =(uint8_t*)&get_sp(current->domain)->sp_global.pic_last_irr;
    9.75 -    pe =(uint8_t*)&get_sp(current->domain)->sp_global.pic_elcr;
    9.76 -    if ( c == &s->pics[0] ) {
    9.77 -         *pl = c->last_irr;
    9.78 -         *pe = c->elcr;
    9.79 -    }
    9.80 -    else {
    9.81 -         *(pl+1) = c->last_irr;
    9.82 -         *(pe+1) = c->elcr;
    9.83 -    }
    9.84 -}
    9.85 -
    9.86  static void pic_reset(void *opaque)
    9.87  {
    9.88      PicState *s = opaque;
    9.89 @@ -300,7 +256,6 @@ static void pic_ioport_write(void *opaqu
    9.90          if (val & 0x10) {
    9.91              /* init */
    9.92              pic_reset(s);
    9.93 -            update_shared_irr(s->pics_state, s);
    9.94              /* deassert a pending interrupt */
    9.95              s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0);
    9.96              s->init_state = 1;
    9.97 @@ -533,8 +488,6 @@ static int intercept_elcr_io(ioreq_t *p)
    9.98          spin_lock_irqsave(&s->lock, flags);
    9.99          elcr_ioport_write((void*)&s->pics[p->addr&1],
   9.100                  (uint32_t) p->addr, (uint32_t)( data & 0xff));
   9.101 -        get_sp(current->domain)->sp_global.pic_elcr =
   9.102 -            s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
   9.103          spin_unlock_irqrestore(&s->lock, flags);
   9.104      }
   9.105      else {
    10.1 --- a/xen/arch/x86/hvm/svm/intr.c	Tue Nov 07 12:31:17 2006 +0000
    10.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Tue Nov 07 13:13:52 2006 +0000
    10.3 @@ -46,12 +46,8 @@
    10.4  static inline int svm_inject_extint(struct vcpu *v, int trap)
    10.5  {
    10.6      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    10.7 -    vintr_t intr;
    10.8 +    vintr_t intr = vmcb->vintr;
    10.9  
   10.10 -    ASSERT(vmcb);
   10.11 -
   10.12 -    /* Save all fields */
   10.13 -    intr = vmcb->vintr;
   10.14      /* Update only relevant fields */    
   10.15      intr.fields.irq = 1;
   10.16      intr.fields.intr_masking = 1;
   10.17 @@ -75,11 +71,10 @@ asmlinkage void svm_intr_assist(void)
   10.18      int intr_vector = -1;
   10.19      int re_injecting = 0;
   10.20  
   10.21 -    ASSERT(vmcb);
   10.22 -
   10.23      /* Check if an Injection is active */
   10.24      /* Previous Interrupt delivery caused this Intercept? */
   10.25 -    if (vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0)) {
   10.26 +    if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
   10.27 +    {
   10.28          v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
   10.29          vmcb->exitintinfo.bytes = 0;
   10.30          re_injecting = 1;
   10.31 @@ -88,70 +83,71 @@ asmlinkage void svm_intr_assist(void)
   10.32      /*
   10.33       * If event requires injecting then do not inject int.
   10.34       */
   10.35 -    if (unlikely(v->arch.hvm_svm.inject_event)) {
   10.36 +    if ( unlikely(v->arch.hvm_svm.inject_event) )
   10.37 +    {
   10.38          v->arch.hvm_svm.inject_event = 0;
   10.39          return;
   10.40      }
   10.41  
   10.42      /*
   10.43 -     * create a 'fake' virtual interrupt on to intercept as soon
   10.44 -     * as the guest _can_ take interrupts
   10.45 +     * Create a 'fake' virtual interrupt on to intercept as soon
   10.46 +     * as the guest _can_ take interrupts.
   10.47       */
   10.48 -    if (irq_masked(vmcb->rflags) || vmcb->interrupt_shadow) {
   10.49 +    if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )
   10.50 +    {
   10.51          vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
   10.52          svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
   10.53          return;
   10.54      }
   10.55  
   10.56      /* Previous interrupt still pending? */
   10.57 -    if (vmcb->vintr.fields.irq) {
   10.58 -//        printk("Re-injecting IRQ from Vintr\n");
   10.59 +    if ( vmcb->vintr.fields.irq )
   10.60 +    {
   10.61          intr_vector = vmcb->vintr.fields.vector;
   10.62          vmcb->vintr.bytes = 0;
   10.63          re_injecting = 1;
   10.64      }
   10.65      /* Pending IRQ saved at last VMExit? */
   10.66 -    else if ( v->arch.hvm_svm.saved_irq_vector >= 0) {
   10.67 -//        printk("Re-Injecting saved IRQ\n");
   10.68 +    else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
   10.69 +    {
   10.70          intr_vector = v->arch.hvm_svm.saved_irq_vector;
   10.71          v->arch.hvm_svm.saved_irq_vector = -1;
   10.72          re_injecting = 1;
   10.73      }
   10.74      /* Now let's check for newer interrrupts  */
   10.75 -    else {
   10.76 -
   10.77 -      if ( v->vcpu_id == 0 )
   10.78 -         hvm_pic_assist(v);
   10.79 -
   10.80 -
   10.81 -      if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr ) {
   10.82 -          pic_set_irq(pic, pt->irq, 0);
   10.83 -          pic_set_irq(pic, pt->irq, 1);
   10.84 -      }
   10.85 +    else
   10.86 +    {
   10.87 +        if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr )
   10.88 +        {
   10.89 +            pic_set_irq(pic, pt->irq, 0);
   10.90 +            pic_set_irq(pic, pt->irq, 1);
   10.91 +        }
   10.92  
   10.93 -      if (v->vcpu_id == 0) {
   10.94 -          callback_irq =
   10.95 -              v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
   10.96 -          if ( callback_irq != 0)
   10.97 -              pic_set_xen_irq(pic, callback_irq, local_events_need_delivery());
   10.98 -      }
   10.99 +        if ( v->vcpu_id == 0 )
  10.100 +        {
  10.101 +            callback_irq =
  10.102 +                v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
  10.103 +            if ( callback_irq != 0 )
  10.104 +                pic_set_xen_irq(pic, callback_irq,
  10.105 +                                local_events_need_delivery());
  10.106 +        }
  10.107  
  10.108 -      if ( cpu_has_pending_irq(v) )
  10.109 -          intr_vector = cpu_get_interrupt(v, &intr_type);
  10.110 -
  10.111 +        if ( cpu_has_pending_irq(v) )
  10.112 +            intr_vector = cpu_get_interrupt(v, &intr_type);
  10.113      }
  10.114  
  10.115      /* have we got an interrupt to inject? */
  10.116 -    if (intr_vector >= 0) {
  10.117 -        switch (intr_type) {
  10.118 +    if ( intr_vector >= 0 )
  10.119 +    {
  10.120 +        switch ( intr_type )
  10.121 +        {
  10.122          case APIC_DM_EXTINT:
  10.123          case APIC_DM_FIXED:
  10.124          case APIC_DM_LOWEST:
  10.125              /* Re-injecting a PIT interruptt? */
  10.126 -            if (re_injecting && pt->enabled && 
  10.127 -                is_periodic_irq(v, intr_vector, intr_type)) {
  10.128 -                    ++pt->pending_intr_nr;
  10.129 -            }
  10.130 +            if ( re_injecting && pt->enabled && 
  10.131 +                 is_periodic_irq(v, intr_vector, intr_type) )
  10.132 +                ++pt->pending_intr_nr;
  10.133              /* let's inject this interrupt */
  10.134              TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, intr_vector, 0);
  10.135              svm_inject_extint(v, intr_vector);
    11.1 --- a/xen/arch/x86/hvm/vioapic.c	Tue Nov 07 12:31:17 2006 +0000
    11.2 +++ b/xen/arch/x86/hvm/vioapic.c	Tue Nov 07 13:13:52 2006 +0000
    11.3 @@ -526,22 +526,6 @@ static void service_ioapic(hvm_vioapic_t
    11.4      }
    11.5  }
    11.6  
    11.7 -void hvm_vioapic_do_irqs(struct domain *d, uint16_t irqs)
    11.8 -{
    11.9 -    hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic);
   11.10 -
   11.11 -    s->irr |= irqs & ~s->imr;
   11.12 -    service_ioapic(s);
   11.13 -}
   11.14 -
   11.15 -void hvm_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs)
   11.16 -{
   11.17 -    hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic);
   11.18 -
   11.19 -    s->irr &= ~irqs;
   11.20 -    service_ioapic(s);
   11.21 -}
   11.22 -
   11.23  void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level)
   11.24  {
   11.25      hvm_vioapic_t *s = &d->arch.hvm_domain.vioapic;
   11.26 @@ -565,12 +549,10 @@ void hvm_vioapic_set_irq(struct domain *
   11.27      HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
   11.28        "irq %x level %x\n", irq, level);
   11.29  
   11.30 -    if (irq < 0 || irq >= IOAPIC_NUM_PINS) {
   11.31 -        printk("ioapic_set_irq irq %x is illegal\n", irq);
   11.32 -        domain_crash_synchronous();
   11.33 -    }
   11.34 +    if ( (irq < 0) || (irq >= IOAPIC_NUM_PINS) )
   11.35 +        return;
   11.36  
   11.37 -    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
   11.38 +    if ( !IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask )
   11.39          return;
   11.40  
   11.41      HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_set_irq entry %x "
    12.1 --- a/xen/arch/x86/hvm/vmx/io.c	Tue Nov 07 12:31:17 2006 +0000
    12.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Tue Nov 07 13:13:52 2006 +0000
    12.3 @@ -104,9 +104,6 @@ asmlinkage void vmx_intr_assist(void)
    12.4      unsigned long inst_len;
    12.5      int    has_ext_irq;
    12.6  
    12.7 -    if ( v->vcpu_id == 0 )
    12.8 -        hvm_pic_assist(v);
    12.9 -
   12.10      if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr ) {
   12.11          pic_set_irq(pic, pt->irq, 0);
   12.12          pic_set_irq(pic, pt->irq, 1);
    13.1 --- a/xen/include/asm-ia64/vlsapic.h	Tue Nov 07 12:31:17 2006 +0000
    13.2 +++ b/xen/include/asm-ia64/vlsapic.h	Tue Nov 07 13:13:52 2006 +0000
    13.3 @@ -24,7 +24,6 @@
    13.4  #define _LSAPIC_H
    13.5  #include <xen/sched.h>
    13.6  
    13.7 -extern void vmx_virq_line_init(struct domain *d);
    13.8  extern void vtm_init(struct vcpu *vcpu);
    13.9  extern void vtm_set_itc(struct  vcpu *vcpu, uint64_t new_itc);
   13.10  extern void vtm_set_itm(struct vcpu *vcpu, uint64_t val);
    14.1 --- a/xen/include/asm-ia64/vmx.h	Tue Nov 07 12:31:17 2006 +0000
    14.2 +++ b/xen/include/asm-ia64/vmx.h	Tue Nov 07 13:13:52 2006 +0000
    14.3 @@ -44,13 +44,11 @@ extern void show_registers(struct pt_reg
    14.4  #define show_execution_state show_registers
    14.5  extern unsigned long __gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
    14.6  extern void sync_split_caches(void);
    14.7 -extern void vmx_virq_line_assist(struct vcpu *v);
    14.8  extern void set_privileged_operation_isr (struct vcpu *vcpu,int inst);
    14.9  extern void privilege_op (struct vcpu *vcpu);
   14.10  extern void set_ifa_itir_iha (struct vcpu *vcpu, u64 vadr,
   14.11            int set_ifa, int set_itir, int set_iha);
   14.12  extern void inject_guest_interruption(struct vcpu *vcpu, u64 vec);
   14.13 -extern void vmx_intr_assist(struct vcpu *v);
   14.14  extern void set_illegal_op_isr (struct vcpu *vcpu);
   14.15  extern void illegal_op (struct vcpu *vcpu);
   14.16  extern void vmx_relinquish_guest_resources(struct domain *d);
    15.1 --- a/xen/include/asm-ia64/vmx_vpd.h	Tue Nov 07 12:31:17 2006 +0000
    15.2 +++ b/xen/include/asm-ia64/vmx_vpd.h	Tue Nov 07 13:13:52 2006 +0000
    15.3 @@ -116,7 +116,6 @@ struct arch_vmx_struct {
    15.4  #define VMX_DOMAIN(v)   v->arch.arch_vmx.flags
    15.5  
    15.6  #define ARCH_VMX_IO_WAIT        3       /* Waiting for I/O completion */
    15.7 -#define ARCH_VMX_INTR_ASSIST    4       /* Need DM's assist to issue intr */
    15.8  #define ARCH_VMX_DOMAIN         5       /* Need it to indicate VTi domain */
    15.9  
   15.10  
    16.1 --- a/xen/include/asm-x86/hvm/io.h	Tue Nov 07 12:31:17 2006 +0000
    16.2 +++ b/xen/include/asm-x86/hvm/io.h	Tue Nov 07 13:13:52 2006 +0000
    16.3 @@ -148,7 +148,6 @@ extern void handle_mmio(unsigned long gp
    16.4  extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
    16.5  extern void hvm_io_assist(struct vcpu *v);
    16.6  extern void pic_irq_request(void *data, int level);
    16.7 -extern void hvm_pic_assist(struct vcpu *v);
    16.8  extern int cpu_get_interrupt(struct vcpu *v, int *type);
    16.9  extern int cpu_has_pending_irq(struct vcpu *v);
   16.10  
    17.1 --- a/xen/include/asm-x86/hvm/vioapic.h	Tue Nov 07 12:31:17 2006 +0000
    17.2 +++ b/xen/include/asm-x86/hvm/vioapic.h	Tue Nov 07 13:13:52 2006 +0000
    17.3 @@ -104,8 +104,6 @@ typedef struct hvm_vioapic {
    17.4  
    17.5  hvm_vioapic_t *hvm_vioapic_init(struct domain *d);
    17.6  
    17.7 -void hvm_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs);
    17.8 -void hvm_vioapic_do_irqs(struct domain *d, uint16_t irqs);
    17.9  void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level);
   17.10  void hvm_vioapic_set_irq(struct domain *d, int irq, int level);
   17.11  
    18.1 --- a/xen/include/asm-x86/hvm/vpic.h	Tue Nov 07 12:31:17 2006 +0000
    18.2 +++ b/xen/include/asm-x86/hvm/vpic.h	Tue Nov 07 13:13:52 2006 +0000
    18.3 @@ -66,7 +66,6 @@ struct hvm_virpic {
    18.4  
    18.5  void pic_set_xen_irq(void *opaque, int irq, int level);
    18.6  void pic_set_irq(struct hvm_virpic *s, int irq, int level);
    18.7 -void pic_set_irq_new(void *opaque, int irq, int level);
    18.8  void pic_init(struct hvm_virpic *s, 
    18.9                void (*irq_request)(void *, int),
   18.10                void *irq_request_opaque);
   18.11 @@ -75,7 +74,5 @@ void register_pic_io_hook(struct domain 
   18.12  int cpu_get_pic_interrupt(struct vcpu *v, int *type);
   18.13  int is_periodic_irq(struct vcpu *v, int irq, int type);
   18.14  int is_irq_enabled(struct vcpu *v, int irq);
   18.15 -void do_pic_irqs (struct hvm_virpic *s, uint16_t irqs);
   18.16 -void do_pic_irqs_clear (struct hvm_virpic *s, uint16_t irqs);
   18.17  
   18.18  #endif  /* __ASM_X86_HVM_VPIC_H__ */  
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/xen/include/public/hvm/hvm_op.h	Tue Nov 07 13:13:52 2006 +0000
    19.3 @@ -0,0 +1,25 @@
    19.4 +#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
    19.5 +#define __XEN_PUBLIC_HVM_HVM_OP_H__
    19.6 +
    19.7 +/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
    19.8 +#define HVMOP_set_param     0
    19.9 +#define HVMOP_get_param     1
   19.10 +struct xen_hvm_param {
   19.11 +    domid_t domid;     /* IN */
   19.12 +    uint32_t index;    /* IN */
   19.13 +    uint64_t value;    /* IN/OUT */
   19.14 +};
   19.15 +typedef struct xen_hvm_param xen_hvm_param_t;
   19.16 +DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
   19.17 +
   19.18 +/* Set the logical level of one of a domain's IRQ lines. */
   19.19 +#define HVMOP_set_irq_level 2
   19.20 +struct xen_hvm_set_irq_level {
   19.21 +    domid_t  domid;    /* Domain to be updated.          */
   19.22 +    uint16_t level;    /* New level of the IRQ (0 or 1). */
   19.23 +    uint32_t irq;      /* IRQ to be updated.             */
   19.24 +};
   19.25 +typedef struct xen_hvm_set_irq_level xen_hvm_set_irq_level_t;
   19.26 +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_irq_level_t);
   19.27 +
   19.28 +#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
    20.1 --- a/xen/include/public/hvm/ioreq.h	Tue Nov 07 12:31:17 2006 +0000
    20.2 +++ b/xen/include/public/hvm/ioreq.h	Tue Nov 07 13:13:52 2006 +0000
    20.3 @@ -56,14 +56,6 @@ struct ioreq {
    20.4  };
    20.5  typedef struct ioreq ioreq_t;
    20.6  
    20.7 -struct global_iodata {
    20.8 -    uint16_t    pic_elcr;
    20.9 -    uint16_t    pic_irr;
   20.10 -    uint16_t    pic_last_irr;
   20.11 -    uint16_t    pic_clear_irr;
   20.12 -};
   20.13 -typedef struct global_iodata global_iodata_t;
   20.14 -
   20.15  struct vcpu_iodata {
   20.16      struct ioreq         vp_ioreq;
   20.17      /* Event channel port */
   20.18 @@ -72,7 +64,6 @@ struct vcpu_iodata {
   20.19  typedef struct vcpu_iodata vcpu_iodata_t;
   20.20  
   20.21  struct shared_iopage {
   20.22 -    struct global_iodata sp_global;
   20.23      struct vcpu_iodata   vcpu_iodata[1];
   20.24  };
   20.25  typedef struct shared_iopage shared_iopage_t;
    21.1 --- a/xen/include/public/hvm/params.h	Tue Nov 07 12:31:17 2006 +0000
    21.2 +++ b/xen/include/public/hvm/params.h	Tue Nov 07 13:13:52 2006 +0000
    21.3 @@ -1,7 +1,9 @@
    21.4  #ifndef __XEN_PUBLIC_HVM_PARAMS_H__
    21.5  #define __XEN_PUBLIC_HVM_PARAMS_H__
    21.6  
    21.7 -/* Parameter space. */
    21.8 +#include "hvm_op.h"
    21.9 +
   21.10 +/* Parameter space for HVMOP_{set,get}_param. */
   21.11  #define HVM_PARAM_CALLBACK_IRQ 0
   21.12  #define HVM_PARAM_STORE_PFN    1
   21.13  #define HVM_PARAM_STORE_EVTCHN 2
   21.14 @@ -10,16 +12,4 @@
   21.15  #define HVM_PARAM_BUFIOREQ_PFN 6
   21.16  #define HVM_NR_PARAMS          7
   21.17  
   21.18 -/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
   21.19 -#define HVMOP_set_param 0
   21.20 -#define HVMOP_get_param 1
   21.21 -
   21.22 -struct xen_hvm_param {
   21.23 -    domid_t domid;     /* IN */
   21.24 -    uint32_t index;    /* IN */
   21.25 -    uint64_t value;    /* IN/OUT */
   21.26 -};
   21.27 -typedef struct xen_hvm_param xen_hvm_param_t;
   21.28 -DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
   21.29 -
   21.30  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */