# HG changeset patch # User Tristan Gingold # Date 1204863273 -3600 # Node ID 687a4068f54284543b52b36b99ea9ea8bdae3ea5 # Parent 94f88355c04d5fb77f93b07918505711502511be Create a vlsapic - viosapic interface. Simplify slightly vlsapic. Signed-off-by: Tristan Gingold diff -r 94f88355c04d -r 687a4068f542 xen/arch/ia64/vmx/viosapic.c --- a/xen/arch/ia64/vmx/viosapic.c Sun Feb 24 06:14:49 2008 +0100 +++ b/xen/arch/ia64/vmx/viosapic.c Fri Mar 07 05:14:33 2008 +0100 @@ -49,36 +49,14 @@ static void viosapic_deliver(struct vios uint16_t dest = viosapic->redirtbl[irq].dest_id; uint8_t delivery_mode = viosapic->redirtbl[irq].delivery_mode; uint8_t vector = viosapic->redirtbl[irq].vector; - struct vcpu *v; ASSERT(spin_is_locked(&viosapic->lock)); - switch ( delivery_mode ) - { - case SAPIC_FIXED: - { - v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest); - vlsapic_set_irq(v, vector); - vcpu_kick(v); - break; - } - case SAPIC_LOWEST_PRIORITY: - { - v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest); - if (viosapic->lowest_vcpu) - v = viosapic->lowest_vcpu; - vlsapic_set_irq(v, vector); - vcpu_kick(v); - break; - } - case SAPIC_PMI: - case SAPIC_NMI: - case SAPIC_INIT: - case SAPIC_EXTINT: - default: - gdprintk(XENLOG_WARNING, "Unsupported delivery mode %d\n", - delivery_mode); - break; - } + + if (vlsapic_deliver_int (viosapic_domain (viosapic), + dest, delivery_mode, vector) < 0) + gdprintk(XENLOG_WARNING, + "viosapic: can't deliver int %u to %u (dm=%u)\n", + vector, dest, delivery_mode); } diff -r 94f88355c04d -r 687a4068f542 xen/arch/ia64/vmx/vlsapic.c --- a/xen/arch/ia64/vmx/vlsapic.c Sun Feb 24 06:14:49 2008 +0100 +++ b/xen/arch/ia64/vmx/vlsapic.c Fri Mar 07 05:14:33 2008 +0100 @@ -107,7 +107,6 @@ static void update_vhpi(VCPU *vcpu, int */ static int vmx_vcpu_unpend_interrupt(VCPU *vcpu, uint8_t vector) { - uint64_t spsr; int ret; if (vector & ~0xff) { @@ -115,9 +114,7 @@ static int vmx_vcpu_unpend_interrupt(VCP return -1; } - local_irq_save(spsr); ret = test_and_clear_bit(vector, &VCPU(vcpu, irr[0])); - local_irq_restore(spsr); if (ret) { vcpu->arch.irq_new_pending = 1; @@ -422,16 +419,13 @@ static int irq_masked(VCPU *vcpu, int h_ */ int vmx_vcpu_pend_interrupt(VCPU *vcpu, uint8_t vector) { - uint64_t spsr; int ret; if (vector & ~0xff) { gdprintk(XENLOG_INFO, "vmx_vcpu_pend_interrupt: bad vector\n"); return -1; } - local_irq_save(spsr); ret = test_and_set_bit(vector, &VCPU(vcpu, irr[0])); - local_irq_restore(spsr); if (!ret) { vcpu->arch.irq_new_pending = 1; @@ -605,16 +599,15 @@ void vmx_vexirq(VCPU *vcpu) generate_exirq (vcpu); } -struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest) -{ - struct vcpu * v; - for_each_vcpu ( d, v ) { - if ( (v->arch.privregs->lid >> 16) == dest ) - return v; - } +struct vcpu *lid_to_vcpu(struct domain *d, uint16_t dest) +{ + int id = dest >> 8; + + /* Fast look: assume EID=0 ID=vcpu_id. */ + if ((dest & 0xff) == 0 && id < MAX_VIRT_CPUS) + return d->vcpu[id]; return NULL; } - /* * To inject INIT to guest, we must set the PAL_INIT entry @@ -641,14 +634,24 @@ static void vmx_inject_guest_pal_init(VC * offset: address offset to IPI space. * value: deliver value. */ -static void vlsapic_deliver_ipi(VCPU *vcpu, uint64_t dm, uint64_t vector) -{ - IPI_DPRINTK("deliver_ipi %lx %lx\n", dm, vector); +static int vcpu_deliver_int(VCPU *vcpu, uint64_t dm, uint64_t vector) +{ + int running = vcpu->is_running; + IPI_DPRINTK("deliver_int %lx %lx\n", dm, vector); switch (dm) { case SAPIC_FIXED: // INT vmx_vcpu_pend_interrupt(vcpu, vector); break; + case SAPIC_LOWEST_PRIORITY: + { + struct vcpu *lowest = vcpu_viosapic(vcpu)->lowest_vcpu; + + if (lowest == NULL) + lowest = vcpu; + vmx_vcpu_pend_interrupt(lowest, vector); + break; + } case SAPIC_PMI: // TODO -- inject guest PMI panic_domain(NULL, "Inject guest PMI!\n"); @@ -663,9 +666,31 @@ static void vlsapic_deliver_ipi(VCPU *vc vmx_vcpu_pend_interrupt(vcpu, 0); break; default: - panic_domain(NULL, "Deliver reserved IPI!\n"); - break; - } + return -EINVAL; + break; + } + + /* Kick vcpu. */ + vcpu_unblock(vcpu); + if (running) + smp_send_event_check_cpu(vcpu->processor); + + return 0; +} + +int vlsapic_deliver_int(struct domain *d, + uint16_t dest, uint64_t dm, uint64_t vector) +{ + VCPU *vcpu; + + vcpu = lid_to_vcpu (d, dest); + if (vcpu == NULL) + return -ESRCH; + + if (!vcpu->is_initialised || test_bit(_VPF_down, &vcpu->pause_flags)) + return -ENOEXEC; + + return vcpu_deliver_int (vcpu, dm, vector); } /* @@ -673,25 +698,8 @@ static void vlsapic_deliver_ipi(VCPU *vc */ void deliver_pal_init(VCPU *vcpu) { - vlsapic_deliver_ipi(vcpu, SAPIC_INIT, 0); -} - -/* - * TODO: Use hash table for the lookup. - */ -static inline VCPU *lid_to_vcpu(struct domain *d, uint8_t id, uint8_t eid) -{ - VCPU *v; - LID lid; - - for_each_vcpu(d, v) { - lid.val = VCPU_LID(v); - if (lid.id == id && lid.eid == eid) - return v; - } - return NULL; -} - + vcpu_deliver_int(vcpu, SAPIC_INIT, 0); +} /* * execute write IPI op. @@ -701,7 +709,8 @@ static void vlsapic_write_ipi(VCPU *vcpu VCPU *targ; struct domain *d = vcpu->domain; - targ = lid_to_vcpu(vcpu->domain, ((ipi_a_t)addr).id, ((ipi_a_t)addr).eid); + targ = lid_to_vcpu(vcpu->domain, + (((ipi_a_t)addr).id << 8) | ((ipi_a_t)addr).eid); if (targ == NULL) panic_domain(NULL, "Unknown IPI cpu\n"); @@ -727,12 +736,10 @@ static void vlsapic_write_ipi(VCPU *vcpu printk("arch_boot_vcpu: huh, already awake!"); } } else { - int running = targ->is_running; - vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, - ((ipi_d_t)value).vector); - vcpu_unblock(targ); - if (running) - smp_send_event_check_cpu(targ->processor); + if (((ipi_d_t)value).dm == SAPIC_LOWEST_PRIORITY + || vcpu_deliver_int(targ, ((ipi_d_t)value).dm, + ((ipi_d_t)value).vector) < 0) + panic_domain(NULL, "Deliver reserved interrupt!\n"); } return; } diff -r 94f88355c04d -r 687a4068f542 xen/include/asm-ia64/vlsapic.h --- a/xen/include/asm-ia64/vlsapic.h Sun Feb 24 06:14:49 2008 +0100 +++ b/xen/include/asm-ia64/vlsapic.h Fri Mar 07 05:14:33 2008 +0100 @@ -70,9 +70,9 @@ extern void vtm_set_itv(struct vcpu *vcp extern void vtm_set_itv(struct vcpu *vcpu, uint64_t val); extern void vmx_vexirq(struct vcpu *vcpu); extern void vhpi_detection(struct vcpu *vcpu); -extern int vmx_vcpu_pend_interrupt(VCPU * vcpu, uint8_t vector); -extern struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest); +extern int vlsapic_deliver_int(struct domain *d, + uint16_t dest, uint64_t dm, uint64_t vector); + extern uint64_t vlsapic_read(struct vcpu *v, uint64_t addr, uint64_t s); extern void vlsapic_write(struct vcpu *v, uint64_t addr, uint64_t s, uint64_t val); -#define vlsapic_set_irq vmx_vcpu_pend_interrupt #endif