static long __do_pirq_guest_eoi(struct domain *d, int pirq)
{
	if ( pirq < 0 || pirq >= NR_IRQS )
		return -EINVAL;
	if ( d->arch.auto_unmask ) {
		evtchn_unmask(d->pirq_to_evtchn[pirq]);
	return pirq_guest_eoi(d, pirq);
}

long do_pirq_guest_eoi(int pirq)
{
	return __do_pirq_guest_eoi(current->domain, pirq);
}

static void
fw_hypercall_ipi (struct pt_regs *regs)
{
	int cpu = regs->r14;
	int vector = regs->r15;
	struct vcpu *targ;
	struct domain *d = current->domain;

	/* Be sure the target exists.  */
	if (cpu >= d->max_vcpus)
		return;
	targ = d->vcpu[cpu];
	if (targ == NULL)
		return;

  	if (vector == XEN_SAL_BOOT_RENDEZ_VEC
	    && (!targ->is_initialised
		|| test_bit(_VPF_down, &targ->pause_flags))) {

		/* First start: initialize vpcu.  */
		if (!targ->is_initialised) {
			if (arch_set_info_guest (targ, NULL) != 0) {
				printk ("arch_boot_vcpu: failure\n");
				return;
			}
		}
			
		/* First or next rendez-vous: set registers.  */
		vcpu_init_regs (targ);
		vcpu_regs (targ)->cr_iip = d->arch.sal_data->boot_rdv_ip;
		vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1;
		vcpu_regs (targ)->b0 = FW_HYPERCALL_SAL_RETURN_PADDR;

		if (test_and_clear_bit(_VPF_down,
				       &targ->pause_flags)) {
			vcpu_wake(targ);
			printk(XENLOG_INFO "arch_boot_vcpu: vcpu %d awaken\n",
			       targ->vcpu_id);
		}
		else
			printk ("arch_boot_vcpu: huu, already awaken!\n");
	}
	else {
		int running = targ->is_running;
		vcpu_pend_interrupt(targ, vector);
		vcpu_unblock(targ);
		if (running)
			smp_send_event_check_cpu(targ->processor);
	}
	return;
}
Beispiel #2
0
long do_pirq_guest_eoi(int pirq)
{
	return __do_pirq_guest_eoi(current->domain, pirq);
}